U Javi, nit uvijek postoji u bilo kojem od sljedećih stanja. Ova stanja su:
- Novi
- Aktivan
- Blokirano / Čeka se
- Vremensko čekanje
- Raskinuto
Objašnjenje različitih stanja niti
Novi: Kad god se kreira nova nit, ona je uvijek u novom stanju. Za nit u novom stanju, kod još nije pokrenut i stoga nije započeo svoje izvršavanje.
Aktivan: Kada nit pozove metodu start(), ona prelazi iz novog stanja u aktivno stanje. Aktivno stanje u sebi sadrži dva stanja: jedno je pokretan , a drugi je trčanje .
Program koji implementira višenitnost dobiva fiksni odsječak vremena za svaku pojedinačnu nit. Svaka pojedina nit radi kratko vrijeme i kada taj dodijeljeni vremenski odsječak završi, nit dobrovoljno prepušta CPU drugoj niti, tako da i druge niti mogu raditi svoj odsječak vremena. Kad god se dogodi takav scenarij, sve one dretve koje su voljne pokrenuti se, čekajući svoj red za pokretanje, leže u stanju pokretanja. U stanju koje se može izvoditi, postoji red u kojem leže niti.
Blokirano ili na čekanju: Kad god je nit neaktivna neko vrijeme (ne trajno), tada je ili nit u blokiranom stanju ili je u stanju čekanja.
Na primjer, nit (recimo da joj je ime A) možda želi ispisati neke podatke s pisača. Međutim, u isto vrijeme, druga nit (recimo da joj je ime B) koristi pisač za ispis nekih podataka. Stoga nit A mora čekati da nit B koristi pisač. Dakle, nit A je u blokiranom stanju. Nit u blokiranom stanju ne može izvršiti nikakvo izvršenje i stoga nikada ne troši niti jedan ciklus središnje procesorske jedinice (CPU). Stoga možemo reći da nit A ostaje neaktivna sve dok planer niti ponovno ne aktivira nit A, koja je u stanju čekanja ili blokiranja.
Kada glavna nit pozove metodu join(), tada se kaže da je glavna nit u stanju čekanja. Glavna nit tada čeka da podređene niti dovrše svoje zadatke. Kada podređene niti završe svoj posao, obavijest se šalje glavnoj niti, koja ponovno premješta nit iz stanja čekanja u aktivno stanje.
Ako postoji mnogo niti u stanju čekanja ili blokiranja, tada je dužnost planera niti odrediti koju će nit odabrati, a koju odbiti, a odabranoj niti tada se daje prilika za pokretanje.
Vremensko čekanje: Ponekad čekanje dovodi do gladovanja. Na primjer, nit (ime joj je A) je ušla u kritični odjeljak koda i ne želi napustiti taj kritični odjeljak. U takvom scenariju, druga nit (ime joj je B) mora čekati vječno, što dovodi do gladovanja. Da bi se izbjegao takav scenarij, vremensko ograničeno stanje čekanja daje se niti B. Dakle, nit leži u stanju čekanja određeni vremenski raspon, a ne zauvijek. Pravi primjer vremenskog čekanja je kada pozovemo metodu sleep() na određenoj niti. Metoda sleep() stavlja nit u vremenski određeno stanje čekanja. Nakon što vrijeme istekne, nit se budi i počinje s izvođenjem od trenutka kada je ranije otišla.
Raskinuto: Nit dostiže stanje završetka zbog sljedećih razloga:
- Kada nit završi svoj posao, tada postoji ili se normalno završava.
Prekinuta nit znači da nit više nije u sustavu. Drugim riječima, nit je mrtva i ne postoji način na koji se mrtva nit može ponovno stvoriti (aktivna nakon ubijanja).
Sljedeći dijagram prikazuje različita stanja uključena u životni ciklus niti.
Implementacija stanja niti
U Javi se trenutno stanje niti može dobiti korištenjem Thread.getState() metoda. The java.lang.Thread.State klasa Jave daje konstante ENUM za predstavljanje stanja niti. Ove konstante su:
konstruktori u Javi
public static final Thread.State NEW
Predstavlja prvo stanje niti koje je NOVO stanje.
public static final Thread.State RUNNABLE
Predstavlja stanje koje se može pokrenuti. To znači da nit čeka u redu za izvođenje.
public static final Thread.State BLOCKED
Predstavlja blokirano stanje. U ovom stanju nit čeka da dobije zaključavanje.
public static final Thread.State WAITING
Predstavlja stanje čekanja. Nit će prijeći u ovo stanje kada pozove metodu Object.wait() ili metodu Thread.join() bez vremenskog ograničenja. Nit u stanju čekanja čeka drugu nit da izvrši svoj zadatak.
public static final Thread.State TIMED_WAITING
Predstavlja vremensko stanje čekanja. Glavna razlika između čekanja i vremenskog čekanja je vremensko ograničenje. Čekanje nema vremensko ograničenje, dok vremenski ograničeno čekanje ima vremensko ograničenje. Nit koja poziva sljedeću metodu dostiže vremensko ograničeno stanje čekanja.
- spavati
- pridruži se s timeoutom
- čekati s timeoutom
- parkUntil
- parkNanos
public static final Thread.State TERMINATED
Predstavlja konačno stanje niti koja je prekinuta ili mrtva. Prekinuta nit znači da je završila svoje izvođenje.
Java program za demonstraciju stanja niti
Sljedeći Java program prikazuje neka od gore definiranih stanja niti.
Naziv 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()); } }
Izlaz:
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
Obrazloženje: Kad god stvorimo novu nit, ta nit postiže novo stanje. Kada se metoda start() pozove na nit, planer niti pomiče tu nit u stanje pokretanja. Kad god se metoda join() pozove na bilo kojoj instanci niti, trenutna nit koja izvršava tu naredbu mora čekati da ova nit završi svoje izvršenje, tj. premjesti tu nit u prekinuto stanje. Stoga, prije nego što se konačna naredba za ispis ispiše na konzoli, program poziva metodu join() na niti t2, tjerajući nit t1 da čeka dok nit t2 završi svoje izvršenje i tako nit t2 dođe u prekinuto ili mrtvo stanje. . Nit t1 prelazi u stanje čekanja jer čeka da nit t2 završi s izvođenjem jer je pozvala metodu join() na niti t2.