logo

Životní cyklus vlákna (stavy vlákna)

V Javě vlákno vždy existuje v kterémkoli z následujících stavů. Tyto stavy jsou:

  1. Nový
  2. Aktivní
  3. Blokováno / Čeká
  4. Časované čekání
  5. Ukončeno

Vysvětlení různých stavů vláken

Nový: Kdykoli je vytvořeno nové vlákno, je vždy v novém stavu. Pro vlákno v novém stavu nebyl kód ještě spuštěn, a proto nezačal s jeho prováděním.

Aktivní: Když vlákno vyvolá metodu start(), přesune se z nového stavu do aktivního stavu. Aktivní stav obsahuje dva stavy: jeden je spustitelný a další je běh .

    Spustitelné:Vlákno, které je připraveno ke spuštění, se poté přesune do spustitelného stavu. V spustitelném stavu může být vlákno spuštěno nebo může být připraveno ke spuštění v jakémkoli daném okamžiku. Povinností plánovače vláken je poskytnout vláknu čas ke spuštění, tj. přesunout vlákno do stavu běhu.
    Program implementující multithreading získává pevný úsek času pro každé jednotlivé vlákno. Každé vlákno běží po krátkou dobu, a když tento přidělený časový úsek skončí, vlákno dobrovolně přenechá CPU druhému vláknu, takže ostatní vlákna mohou také běžet po svůj úsek času. Kdykoli dojde k takovému scénáři, všechna vlákna, která jsou ochotna běžet a čekají, až na ně přijde řada, leží v spustitelném stavu. V spustitelném stavu existuje fronta, kde leží vlákna.Běh:Když vlákno získá CPU, přesune se z spustitelného do běžícího stavu. Obecně je nejběžnější změnou stavu vlákna ze spustitelného na spuštěné a znovu zpět na spustitelné.

Blokováno nebo čekání: Kdykoli je vlákno po určitou dobu neaktivní (nikoli trvale), pak je vlákno buď v blokovaném stavu, nebo ve stavu čekání.

Například vlákno (řekněme, že jeho název je A) může chtít vytisknout některá data z tiskárny. Současně však druhé vlákno (řekněme, že se jmenuje B) používá tiskárnu k tisku některých dat. Proto vlákno A musí počkat, až vlákno B použije tiskárnu. Vlákno A je tedy v zablokovaném stavu. Vlákno v zablokovaném stavu není schopno provést žádné spuštění, a proto nikdy nespotřebuje žádný cyklus centrální procesorové jednotky (CPU). Můžeme tedy říci, že vlákno A zůstává nečinné, dokud plánovač vláken znovu neaktivuje vlákno A, které je ve stavu čekání nebo blokování.

Když pak hlavní vlákno vyvolá metodu join(), říká se, že hlavní vlákno je ve stavu čekání. Hlavní vlákno pak čeká, až podřízená vlákna dokončí své úkoly. Když podřízená vlákna dokončí svou úlohu, hlavnímu vláknu se odešle oznámení, které vlákno opět přesune z čekání do aktivního stavu.

Pokud je ve stavu čekání nebo blokování mnoho vláken, pak je povinností plánovače vláken určit, které vlákno zvolit a které odmítnout, a zvolené vlákno pak dostane příležitost ke spuštění.

Časované čekání: Někdy čekání vede k hladovění. Například vlákno (jeho jméno je A) vstoupilo do kritické části kódu a nechce tuto kritickou sekci opustit. V takovém scénáři musí další vlákno (jmenuje se B) čekat navždy, což vede k hladovění. Aby se předešlo takovému scénáři, je vláknu B dán stav časovaného čekání. Vlákno tedy leží ve stavu čekání po určitou dobu a ne navždy. Skutečným příkladem časovaného čekání je, když vyvoláme metodu sleep() na konkrétním vláknu. Metoda sleep() uvede vlákno do stavu časovaného čekání. Po vypršení času se vlákno probudí a spustí se od okamžiku, kdy dříve odešlo.

Ukončeno: Vlákno dosáhne stavu ukončení z následujících důvodů:

  • Když vlákno dokončí svou úlohu, existuje nebo se normálně ukončí.
  • Abnormální ukončení:Vyskytuje se při neobvyklých událostech, jako je neošetřená výjimka nebo chyba segmentace.

Ukončené vlákno znamená, že vlákno již není v systému. Jinými slovy, vlákno je mrtvé a neexistuje způsob, jak se mrtvé vlákno znovu spustit (aktivní po zabití).

Následující diagram ukazuje různé stavy zahrnuté v životním cyklu vlákna.

Životní cyklus vlákna Java

Implementace stavů vláken

V Javě lze získat aktuální stav vlákna pomocí Thread.getState() metoda. The java.lang.Thread.State třída Java poskytuje konstanty ENUM, které reprezentují stav vlákna. Tyto konstanty jsou:

seznam vytváření java
 public static final Thread.State NEW 

Představuje první stav vlákna, který je NEW stavem.

 public static final Thread.State RUNNABLE 

Představuje spustitelný stav. Znamená to, že vlákno čeká ve frontě na spuštění.

 public static final Thread.State BLOCKED 

Představuje blokovaný stav. V tomto stavu vlákno čeká na získání zámku.

 public static final Thread.State WAITING 

Představuje stav čekání. Vlákno přejde do tohoto stavu, když vyvolá metodu Object.wait() nebo Thread.join() bez časového limitu. Vlákno ve stavu čekání čeká, až jiné vlákno dokončí svůj úkol.

 public static final Thread.State TIMED_WAITING 

Představuje stav časovaného čekání. Hlavním rozdílem mezi čekáním a časovaným čekáním je časové omezení. Čekání nemá žádné časové omezení, zatímco časované čekání má časové omezení. Vlákno vyvolávající následující metodu dosáhne stavu časovaného čekání.

  • spát
  • připojit se s časovým limitem
  • čekat s časovým limitem
  • parkDokud
  • parkNanos
 public static final Thread.State TERMINATED 

Představuje konečný stav vlákna, které je ukončeno nebo mrtvé. Ukončené vlákno znamená, že dokončilo své provádění.

Program Java pro demonstraci stavů vláken

Následující program Java ukazuje některé stavy vlákna definovaného výše.

Název souboru: 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()); } } 

Výstup:

 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 

Vysvětlení: Kdykoli vytvoříme nové vlákno, toto vlákno dosáhne nového stavu. Když je na vlákně vyvolána metoda start(), plánovač vláken přesune toto vlákno do spustitelného stavu. Kdykoli je v jakékoli instanci vlákna vyvolána metoda join(), aktuální vlákno provádějící tento příkaz musí počkat, až toto vlákno dokončí své provádění, tj. přesunout vlákno do stavu ukončení. Proto před vytištěním konečného tiskového příkazu na konzole program vyvolá metodu join() na vlákně t2, čímž nechá vlákno t1 čekat, dokud vlákno t2 dokončí své provádění, a tak se vlákno t2 dostane do ukončeného nebo mrtvého stavu. . Vlákno t1 přejde do stavu čekání, protože čeká, až vlákno t2 dokončí své provádění, protože vyvolalo metodu join() ve vláknu t2.