| Home |
last update: 1997-04-08 |
Multithreading v Jave
Základy
2 možnosti práce s thready:
-
buď podědit od třídy Thread
class SimpleThread extends Thread {
public SimpleThread(String str) {
super(str);
}
public void run() {
...
}
}
-
nebo implementovat rozhraní Runnable
class Sender implements Runnable
{
public void run()
{
...
}
...
}
Stavy a priorita threadů
Stavy threadu
Kdy se thread dotstane do stavu Not Runnable:
-
Je zavolána metoda sleep().
-
Je zavolána metoda suspend().
-
Thread se uspí pomocí wait().
-
Thread je zablokován nějakou vstupně/výstupní operací.
-
stav threadu lze zjistit metodou isAlive()
Výběr threadu, který poběží:
poznámka: priorita threadů v Javě je statická!
-
vždy se spustí thread s nejvyšší prioritou
-
pokud je více se stejnou prioritou, dostávají se ke slovu postupně,
dle násladujícího mechanismu:
-
thread s vyšší prioritou se stane "Runnable"
v tomto případě funguje VM preemptivně - dosud běžící thread se okamžitě
přeruší
-
běžící thread zavolá yield(), sleep(),
nebo skončí
-
hostitelský systém podporuje tzv. "time-slicing" - preemptivní multitasking
s časovými kvanty a thread přeruší
Volba priority threadu: metoda setPriority()
hodnota musí být v rozmezí MAX_PRIORITY (=10) a MIN_PRIORITY
(=1)
Daemon Threads
tzv. "Daemon Threads"
- podobně jako daemoni v Unixu, poskytuji služby ostatním threadům v
procesu
- dokud běží alespoň jeden daemon thread, zůstane běžet VM Javy
- metody setDaemon(), isDaemon()
Skupiny (Groups) threadů
public Thread(ThreadGroup group, Runnable target)
public Thread(ThreadGroup group, String name)
public Thread(ThreadGroup group, Runnable target, String name)
Příklad:
ThreadGroup myThreadGroup = new ThreadGroup("My Group of Threads");
Thread myThread = new Thread(myThreadGroup, "a thread for my group");
Schéma možné hierarchie threadů
-
implicitně je tedy každý thread členem skupiny "main"
-
lze však explicitně říci, do které skupiny má patřit
-
zjištění v jaké je thread skupině se provádí následující konstrukcí:
theGroup = myThread.getThreadGroup();
-
práce s thready a skupinami threadů sdružených v jedné skupině lze
rozdělit na zhruba následujíci skupiny operací:
-
Práce se sbírkami (collections)
-
Práce se skupinou - změny jejích atributů
-
Prace se všemy thready ve skupině
-
Řízení přístupových práv (ve spolupráci se třídou SecurityManager)
Synchronizace threadů v Jave
-
klíčové slovo synchronized
-
na úrovni sekce - myšleno metody objektu, teoreticky by mělo
jít napsat i toto:
...
synchronized{
...
}
leč v dokumentaci to nedoporučují :-)
-
jestliže deklarujeme nějakou metodu objektu jako synchronized, je
instanci objektu přiřazen jednoznačný tzv. Monitor;
vechvíli volání metody deklarované jako synchronized získáva
thread který tuto metody zavolat monitor, a žádný jiný thread nemůže zavolat
žádnou jinou metodu daného objektu, definovanou jako synchronized.
-
monitor se tedy váže k instanci objektu.
-
monitor je tzv. reentrantní; znamená to, že thread, který vlastní
pro danou chvíli monitor, může volat další synchronized metody
daného objektu.
-
thread, který se pokouší spustit synchronized metodu
objektu, pro který nemá monitor, je automaticky pozastaven
-
avšak většinou potřebujeme synchronizaci na trochu vyšší úrovni
- splnění určitých podmínek. K tomu slouží metody wait() a dvojice metod
notify(), notifyAll(). (Ukázka viz níže v příkladu.)
Tedy pokud není splněna určitá podmínka a thread nemůže pokračovat v
činnosti, uspí se metodou wait(). A čeká na změnu situace.
Thread, který situaci změní, zavolá buď metodu notify(), případně notifAll().
A tím probudí čekající thread/thready.
Příklad:
Problém producent - konzument v Jave
První - úplně špatná - varianta
Třetí - správná - varianta
Zdroje:
Java
Tutorial
JDK
1.1 Documentation
Softwarové noviny 1/97