V Javi nit vedno obstaja v enem od naslednjih stanj. Ta stanja so:
- Novo
- Aktiven
- Blokirano/čaka
- Časovno čakanje
- Prekinjeno
Razlaga različnih stanj niti
Novo: Kadarkoli je ustvarjena nova nit, je vedno v novem stanju. Za nit v novem stanju koda še ni bila zagnana in se zato ni začela z izvajanjem.
aktivno: Ko nit prikliče metodo start(), se premakne iz novega stanja v aktivno stanje. Aktivno stanje vsebuje v sebi dve stanji: eno je tečljiv , drugi pa je teče .
Program, ki izvaja večnitnost, pridobi fiksni del časa za vsako posamezno nit. Vsaka nit teče kratek čas in ko se ta dodeljena časovna rezina konča, nit prostovoljno preda CPU drugi niti, tako da lahko tudi druge niti delujejo svoj del časa. Kadarkoli pride do takšnega scenarija, so vse tiste niti, ki se želijo izvajati in čakajo, da pridejo na vrsto za izvajanje, v stanju izvajanja. V zagonskem stanju obstaja čakalna vrsta, v kateri ležijo niti.
Blokirano ali čaka: Kadarkoli je nit neaktivna določen čas (ne trajno), je nit bodisi v blokiranem stanju bodisi v stanju čakanja.
Na primer, nit (recimo, da je njeno ime A) morda želi natisniti nekaj podatkov iz tiskalnika. Vendar istočasno druga nit (recimo, da je njeno ime B) uporablja tiskalnik za tiskanje nekaterih podatkov. Zato mora nit A počakati, da nit B uporabi tiskalnik. Tako je nit A v blokiranem stanju. Nit v blokiranem stanju ne more izvesti nobene izvedbe in tako nikoli ne porabi nobenega cikla centralne procesne enote (CPE). Zato lahko rečemo, da nit A ostane nedejavna, dokler razporejevalnik niti ponovno ne aktivira niti A, ki je v čakajočem ali blokiranem stanju.
Ko glavna nit takrat prikliče metodo join(), se reče, da je glavna nit v stanju čakanja. Glavna nit nato čaka, da podrejene niti dokončajo svoje naloge. Ko podrejene niti dokončajo svoje delo, se glavni niti pošlje obvestilo, ki ponovno premakne nit iz čakajočega v aktivno stanje.
Če je veliko niti v čakajočem ali blokiranem stanju, je dolžnost razporejevalnika niti določiti, katero nit naj izbere in katero zavrne, izbrana nit pa dobi možnost izvajanja.
Časovno čakanje: Včasih čakanje vodi v lakoto. Na primer, nit (njeno ime je A) je vstopila v kritični odsek kode in tega kritičnega odseka ne želi zapustiti. V takem scenariju mora druga nit (njeno ime je B) čakati večno, kar vodi v stradanje. Da bi se izognili takšnemu scenariju, se niti B dodeli časovno določeno čakalno stanje. Tako je nit v čakajočem stanju določeno časovno obdobje in ne za vedno. Pravi primer časovno omejenega čakanja je, ko prikličemo metodo sleep() na določeni niti. Metoda sleep() postavi nit v časovno določeno čakajoče stanje. Ko se čas izteče, se nit prebudi in začne izvajati od takrat, ko je prej zapustila.
Prekinjeno: Nit doseže končno stanje zaradi naslednjih razlogov:
- Ko nit zaključi svoje delo, obstaja ali se normalno zaključi.
Prekinjena nit pomeni, da ni več v sistemu. Z drugimi besedami, nit je mrtva in mrtve niti ni mogoče ponovno ustvariti (aktivno po uničenju).
Naslednji diagram prikazuje različna stanja, vključena v življenjski cikel niti.
Implementacija stanj niti
V Javi je mogoče pridobiti trenutno stanje niti z uporabo Thread.getState() metoda. The java.lang.Thread.State razred Jave nudi konstante ENUM za predstavitev stanja niti. Te konstante so:
jvm v Javi
public static final Thread.State NEW
Predstavlja prvo stanje niti, ki je NOVO stanje.
public static final Thread.State RUNNABLE
Predstavlja zagonsko stanje. Pomeni, da nit čaka v čakalni vrsti na izvajanje.
public static final Thread.State BLOCKED
Predstavlja blokirano stanje. V tem stanju nit čaka na pridobitev zaklepanja.
public static final Thread.State WAITING
Predstavlja stanje čakanja. Nit bo prešla v to stanje, ko pokliče metodo Object.wait() ali metodo Thread.join() brez časovne omejitve. Nit v stanju čakanja čaka na drugo nit, da dokonča njeno nalogo.
public static final Thread.State TIMED_WAITING
Predstavlja časovno določeno čakalno stanje. Glavna razlika med čakanjem in časovno določenim čakanjem je časovna omejitev. Čakanje nima časovne omejitve, medtem ko ima časovno omejeno čakanje časovno omejitev. Nit, ki kliče naslednjo metodo, doseže časovno določeno čakalno stanje.
- spati
- pridruži se s časovno omejitvijo
- počakajte s časovno omejitvijo
- parkUntil
- parkNanos
public static final Thread.State TERMINATED
Predstavlja končno stanje niti, ki je prekinjena ali mrtva. Prekinjena nit pomeni, da je zaključila svojo izvedbo.
Program Java za prikaz stanja niti
Naslednji program Java prikazuje nekatera stanja niti, definirane zgoraj.
Ime datoteke: ThreadState.java
// ABC class implements the interface Runnable class ABC implements Runnable { public void run() { // try-catch block try { // moving thread t2 to the state timed waiting Thread.sleep(100); } catch (InterruptedException ie) { ie.printStackTrace(); } System.out.println('The state of thread t1 while it invoked the method join() on thread t2 -'+ ThreadState.t1.getState()); // try-catch block try { Thread.sleep(200); } catch (InterruptedException ie) { ie.printStackTrace(); } } } // ThreadState class implements the interface Runnable public class ThreadState implements Runnable { public static Thread t1; public static ThreadState obj; // main method public static void main(String argvs[]) { // creating an object of the class ThreadState obj = new ThreadState(); t1 = new Thread(obj); // thread t1 is spawned // The thread t1 is currently in the NEW state. System.out.println('The state of thread t1 after spawning it - ' + t1.getState()); // invoking the start() method on // the thread t1 t1.start(); // thread t1 is moved to the Runnable state System.out.println('The state of thread t1 after invoking the method start() on it - ' + t1.getState()); } public void run() { ABC myObj = new ABC(); Thread t2 = new Thread(myObj); // thread t2 is created and is currently in the NEW state. System.out.println('The state of thread t2 after spawning it - '+ t2.getState()); t2.start(); // thread t2 is moved to the runnable state System.out.println('the state of thread t2 after calling the method start() on it - ' + t2.getState()); // try-catch block for the smooth flow of the program try { // moving the thread t1 to the state timed waiting Thread.sleep(200); } catch (InterruptedException ie) { ie.printStackTrace(); } System.out.println('The state of thread t2 after invoking the method sleep() on it - '+ t2.getState() ); // try-catch block for the smooth flow of the program try { // waiting for thread t2 to complete its execution t2.join(); } catch (InterruptedException ie) { ie.printStackTrace(); } System.out.println('The state of thread t2 when it has completed it's execution - ' + t2.getState()); } }
Izhod:
The state of thread t1 after spawning it - NEW The state of thread t1 after invoking the method start() on it - RUNNABLE The state of thread t2 after spawning it - NEW the state of thread t2 after calling the method start() on it - RUNNABLE The state of thread t1 while it invoked the method join() on thread t2 -TIMED_WAITING The state of thread t2 after invoking the method sleep() on it - TIMED_WAITING The state of thread t2 when it has completed it's execution - TERMINATED
Pojasnilo: Kadar koli ustvarimo novo nit, ta nit doseže novo stanje. Ko se metoda start() prikliče v niti, razporejevalnik niti premakne to nit v stanje, ki ga je mogoče izvajati. Kadarkoli je metoda join() priklicana na katerem koli primerku niti, mora trenutna nit, ki izvaja ta stavek, počakati, da ta nit zaključi svoje izvajanje, tj. premakne to nit v prekinjeno stanje. Zato, preden se na konzoli natisne končni stavek za tiskanje, program prikliče metodo join() na nit t2, zaradi česar nit t1 počaka, da nit t2 konča svojo izvedbo in tako nit t2 pride v prekinjeno ali mrtvo stanje. . Nit t1 preide v stanje čakanja, ker čaka, da nit t2 zaključi njeno izvajanje, saj je priklicala metodo join() v niti t2.