Lõim pärib oma prioriteedi sellelt lõimelt, mis ta tekitas.
Klassis Thread on täisarvulised konstandid MIN_PRIORITY, NORM_PRIORITY ja MAX_PRIORITY (kasvamise järjekorras), mida saab kasutada lõime prioriteedi muutmiseks meetodiga setPriority(). Antud lõime prioriteedi tagastab meetod getPriority().
Pole mingit mõtet anda lõimedele maksimaalset prioriteeti - olukord sellest tavaliselt ei parane. Pigem on otstarbekas osade lõimede prioriteete vähendada.
Näit.:
int prio = Thread.NORM_PRIORITY -
tagaPlaan.start();
Sisenemisel "kriitilisse sektsiooni" objekt lukustatakse, teised lõimed saavad objekti kasutada alles siis, kui lukk on maha võetud, s.t. esialgne lõim on "kriitilisest sektsioonist" väljas.
Lukustamise ja lukkude eemaldamise mehhanismi tuntakse ka monitori nime all. Iga objektiga (ja ka iga klassiga) on seotud oma monitor, seepärast ongi wait(),notify() ja notifyAll() klassi Object isendimeetodid.
obj.wait() peatab jooksva lõime töö ning avab obj luku niikauaks, kuni mingi teine lõim saadab teate obj.notify(). Leidub ka üledefineeritud wait(ms) versioon, mille toimel lõim siiski "ärkab" etteantud aja möödudes.
Kuna sama objekti obj taga võib olla mitu ootajat, siis tuleks tegelikult kasutada obj.notifyAll(), mis "äratab" kõik obj järele ootajad (see, mis edasi juhtub, on prioriteetide ja ajajaotuse küsimus; kui võitja on selgunud, siis lähevad ülejäänud lõimed ooteseisundisse tagasi).
Kõiki neid meetodeid kasutatakse kriitilise sektsiooni sees.
/*
* Fail TootjadTarbijad.java
*/
//======================================================
// Klassikaline tootja-tarbija u"lesanne
//======================================================
import java.util.*;
public class TootjadTarbijad {
static final int PUHVRIPIKKUS = 6;
static Vector yhispuhver = new Vector (PUHVRIPIKKUS);
public static void main (String[] parameetrid) {
int tootja1_tiks = 5000; //millisekundit
int tootja2_tiks = 7000; //millisekundit
int tarbija1_tiks = 3000; //millisekundit
Tootja tootja1 =
new Tootja (yhispuhver, tootja1_tiks, "Pro1");
Tootja tootja2 =
new Tootja (yhispuhver, tootja2_tiks, "Pro2");
Tarbija tarbija1 =
new Tarbija (yhispuhver, tarbija1_tiks, "Con1");
System.out.println
("Puhvri suurus: " + yhispuhver.capacity());
tootja1.start();
tootja2.start();
tarbija1.start();
} // main lopp
} // TootjadTarbijad lopp
class Tootja extends Thread {
Vector puhver;
int tiks;
String nimi;
Tootja (Vector v, int i, String s) {
puhver = v;
tiks = i;
nimi = s;
}
public void run() {
try {
while (true) { //lopmatu tsykkel
tooda(); //iga tiksuga toodab uue asja
sleep (tiks);
}
}
catch (InterruptedException e) {
}
}
private void tooda()
throws InterruptedException {
synchronized (puhver) {
while (puhver.size() >= puhver.capacity()) {
puhver.wait(); //puhver on ta"is, oota
}
puhver.addElement ("(" + nimi + " > " +
new Date().toString() + ")"); //ajatempel
System.out.println (nimi + " > " +
puhver.lastElement() +
" " + tiks + " " + puhver.size());
puhver.notifyAll();
} // kriitilise sektsiooni lopp
}
} // Tootja lopp
class Tarbija extends Thread {
Vector puhver;
int tiks;
String nimi;
Tarbija (Vector v, int i, String s) {
puhver = v;
tiks = i;
nimi = s;
}
public void run() {
try {
while (true) { //lopmatu tsykkel
tarbi(); //iga tiksuga tarbib u"he asja
sleep (tiks);
}
}
catch (InterruptedException e) {
}
}
private void tarbi()
throws InterruptedException {
synchronized (puhver) {
while (puhver.size() <= 0) {
puhver.wait(); //oota, kuni midagi tekib
}
String teade = (String)puhver.firstElement();
System.out.println (nimi + " < " +
teade + " " + tiks);
puhver.removeElementAt (0);
puhver.notifyAll();
} // kriitilise sektsiooni lopp
}
} // Tarbija lopp
// faili lopp
import java.util.*;
public class TootjadTarbijad_Runnable {
static final int PUHVRIPIKKUS = 6;
static Vector yhispuhver = new Vector (PUHVRIPIKKUS);
public static void main (String[] parameetrid) {
int tootja1_tiks = 5000; //millisekundit
int tootja2_tiks = 7000; //millisekundit
int tarbija1_tiks = 3000; //millisekundit
System.out.println
("Puhvri suurus: " + yhispuhver.capacity());
Tootja tootja1 =
new Tootja (yhispuhver, tootja1_tiks, "Pro1");
Tootja tootja2 =
new Tootja (yhispuhver, tootja2_tiks, "Pro2");
Tarbija tarbija1 =
new Tarbija (yhispuhver, tarbija1_tiks, "Con1");
} // main lopp
} // TootjadTarbijad_Runnable lopp
//=======================================================
class Tootja implements Runnable {
Vector puhver;
int tiks;
String nimi;
Thread loim;
// tootja ise ei ole lo~im, ta sisaldab lo~ime
Tootja (Vector v, int i, String s) {
puhver = v;
tiks = i;
nimi = s;
loim = new Thread(this); // this on meil Runnable!
loim.start(); // loomine sisaldab ka ka"ivitamise
}
public void run() {
try {
while (true) { //lopmatu tsykkel
tooda(); //iga tiksuga toodab uue asja
loim.sleep (tiks);
}
}
catch (InterruptedException e) {
}
}
private void tooda()
throws InterruptedException {
synchronized (puhver) {
while (puhver.size() >= puhver.capacity()) {
puhver.wait(); //puhver on ta"is, oota
}
puhver.addElement ("(" + nimi + " > " +
new Date().toString() + ")"); //ajatempel
System.out.println (nimi + " > " +
puhver.lastElement() +
" " + tiks + " " + puhver.size());
puhver.notifyAll();
} // kriitilise sektsiooni lopp
}
} // Tootja lopp
//=======================================================
class Tarbija implements Runnable {
Vector puhver;
int tiks;
String nimi;
Thread loim;
Tarbija (Vector v, int i, String s) {
puhver = v;
tiks = i;
nimi = s;
loim = new Thread (this);
loim.start();
}
public void run() {
try {
while (true) { //lopmatu tsykkel
tarbi(); //iga tiksuga tarbib u"he asja
loim.sleep (tiks);
}
}
catch (InterruptedException e) {
}
}
private void tarbi()
throws InterruptedException {
synchronized (puhver) {
while (puhver.size() <= 0) {
puhver.wait(); //oota, kuni midagi tekib
}
String teade = (String)puhver.firstElement();
System.out.println (nimi + " < " +
teade + " " + tiks);
puhver.removeElementAt (0);
puhver.notifyAll();
} // kriitilise sektsiooni lopp
}
} // Tarbija lopp
Vt. veel lõimerühmad java.lang.ThreadGroup ja serverlõimed (daemon threads): meetodid setDaemon() ja isDaemon().
import java.applet.Applet; // meie kell on vormilt rakend
import java.awt.*;
import java.awt.event.*;
import java.util.Date; // meie kell kasutab Date va"ljundit
public class Kell extends Applet implements Runnable {
private Thread loim;
int tiks = 1000;
public static void main (String[] parameetrid) {
// saame ka ka"surealt ka"ivitada
Frame raam = new Frame ("Minu tehtud kell");
raam.setSize (350,80);
Kell minuKell = new Kell();
raam.add (minuKell);
raam.setVisible (true); // kell ekraanile
raam.addWindowListener (new WindowAdapter () {
public void windowClosing (WindowEvent e) {
System.exit (0);
}
} );
minuKell.run(); // kell ka"ima!
}
public void run() {
while (true) {
try {
Thread.sleep (tiks); //magamisaeg on millisekundites
}
catch (InterruptedException e) {
}
repaint(); // kella seisu va"rskendamine
}
}
public void paint (Graphics ekraan) { // Container meetod
ekraan.drawString (new Date().toString(), 50, 25);
// jooksev aeg stringina va"ljastatakse antud kohta
}
public void start() { // NB! see on Applet-alamklassi start()
if (loim == null) {
loim = new Thread (this); // "this" on meil Runnable
loim.start(); // seega this.run() la"heb ka"ima
} else {
loim.resume(); //loim tegevus taastatakse
}
}
public void stop() { // Applet!
loim.suspend();
}
public void destroy() { // Applet!
if (loim != null) {
loim.stop(); // Thread-klassi stop()
loim = null; // kuulutame surnuks
} //else ongi surnud
}
} // Kell lopp