logo

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

V Jave vlákno vždy existuje v ktoromkoľvek z nasledujúcich stavov. Ide o tieto štáty:

  1. Nový
  2. Aktívne
  3. Blokované / Čaká sa
  4. Načasované čakanie
  5. Ukončené

Vysvetlenie rôznych stavov vlákien

Nový: Vždy, keď sa vytvorí nové vlákno, je vždy v novom stave. Pre vlákno v novom stave kód ešte nebol spustený, a teda nezačal s jeho vykonávaním.

Aktívne: Keď vlákno vyvolá metódu start(), presunie sa z nového stavu do aktívneho stavu. Aktívny stav obsahuje dva stavy: jeden je spustiteľný , a druhý je beh .

    Spustiteľné:Vlákno, ktoré je pripravené na spustenie, sa potom presunie do spustiteľného stavu. V spustenom stave môže byť vlákno spustené alebo môže byť pripravené na spustenie v akomkoľvek danom okamihu. Povinnosťou plánovača vlákien je poskytnúť vlákno čas na spustenie, t. j. presunúť vlákno do stavu spustenia.
    Program implementujúci multithreading získava pevný úsek času pre každé jednotlivé vlákno. Každé vlákno beží na krátky čas a keď tento pridelený časový úsek skončí, vlákno dobrovoľne odovzdá CPU druhému vláknu, takže ostatné vlákna môžu tiež bežať počas svojho časového úseku. Kedykoľvek dôjde k takémuto scenáru, všetky vlákna, ktoré sú ochotné bežať a čakajú, kým na ne príde rad, ležia v spustiteľnom stave. V spustenom stave existuje front, kde ležia vlákna.Beží:Keď vlákno dostane CPU, presunie sa zo spustiteľného do spusteného stavu. Vo všeobecnosti je najbežnejšou zmenou stavu vlákna zo spustiteľného na spustené a znova späť na spustiteľné.

Blokované alebo čakajúce: Kedykoľvek je vlákno nejaký čas neaktívne (nie trvalo), potom je vlákno buď v zablokovanom stave, alebo je v stave čakania.

Napríklad vlákno (povedzme, že jeho názov je A) môže chcieť vytlačiť niektoré údaje z tlačiarne. Zároveň však druhé vlákno (povedzme, že sa volá B) používa tlačiareň na tlač niektorých údajov. Preto vlákno A musí počkať, kým vlákno B použije tlačiareň. Vlákno A je teda v zablokovanom stave. Vlákno v zablokovanom stave nie je schopné vykonať žiadne spustenie, a preto nikdy nespotrebuje žiadny cyklus centrálnej procesorovej jednotky (CPU). Môžeme teda povedať, že vlákno A zostáva nečinné, kým plánovač vlákien znovu neaktivuje vlákno A, ktoré je v čakacom alebo zablokovanom stave.

Keď potom hlavné vlákno vyvolá metódu join(), hovorí sa, že hlavné vlákno je v stave čakania. Hlavné vlákno potom čaká, kým podradené vlákna dokončia svoje úlohy. Keď podradené vlákna dokončia svoju úlohu, hlavnému vláknu sa odošle upozornenie, ktoré vlákno opäť presunie z čakania do aktívneho stavu.

Ak je v čakacom alebo zablokovanom stave veľa vlákien, potom je povinnosťou plánovača vlákien určiť, ktoré vlákno si vybrať a ktoré odmietnuť, a zvolené vlákno potom dostane príležitosť spustiť sa.

Načasované čakanie: Čakanie niekedy vedie k hladovaniu. Napríklad vlákno (jeho názov je A) vstúpilo do kritickej časti kódu a nechce túto kritickú časť opustiť. V takomto scenári musí ďalšie vlákno (jeho názov je B) čakať večne, čo vedie k hladovaniu. Aby sa predišlo takémuto scenáru, vláknu B sa pridelí časovaný stav čakania. Vlákno teda leží v stave čakania počas určitého časového úseku a nie navždy. Skutočným príkladom časovaného čakania je, keď vyvoláme metódu sleep() na konkrétnom vlákne. Metóda sleep() uvedie vlákno do stavu časovaného čakania. Po uplynutí času sa vlákno prebudí a spustí sa od okamihu, keď predtým odišlo.

Ukončené: Vlákno dosiahne stav ukončenia z nasledujúcich dôvodov:

  • Keď vlákno dokončí svoju úlohu, potom existuje alebo sa normálne ukončí.
  • Abnormálne ukončenie:Vyskytuje sa pri niektorých neobvyklých udalostiach, ako je napríklad neošetrená výnimka alebo chyba segmentácie.

Ukončené vlákno znamená, že vlákno už nie je v systéme. Inými slovami, vlákno je mŕtve a neexistuje žiadny spôsob, ako by sa mŕtve vlákno mohlo obnoviť (aktívne po zabití).

Nasledujúci diagram zobrazuje rôzne stavy zahrnuté v životnom cykle vlákna.

Životný cyklus vlákna Java

Implementácia stavov vlákien

V Jave je možné získať aktuálny stav vlákna pomocou Thread.getState() metóda. The java.lang.Thread.State trieda Java poskytuje konštanty ENUM, ktoré reprezentujú stav vlákna. Tieto konštanty sú:

base64 dekódovať v js
 public static final Thread.State NEW 

Predstavuje prvý stav vlákna, ktorý je novým stavom.

 public static final Thread.State RUNNABLE 

Predstavuje spustiteľný stav. Znamená to, že vlákno čaká vo fronte na spustenie.

 public static final Thread.State BLOCKED 

Predstavuje zablokovaný stav. V tomto stave vlákno čaká na získanie zámku.

 public static final Thread.State WAITING 

Predstavuje stav čakania. Vlákno prejde do tohto stavu, keď vyvolá metódu Object.wait() alebo Thread.join() bez časového limitu. Vlákno v stave čakania čaká, kým iné vlákno dokončí svoju úlohu.

 public static final Thread.State TIMED_WAITING 

Predstavuje časovaný stav čakania. Hlavným rozdielom medzi čakaním a časovým čakaním je časové obmedzenie. Čakanie nemá žiadne časové obmedzenie, zatiaľ čo časované čakanie má časové obmedzenie. Vlákno vyvolávajúce nasledujúcu metódu dosiahne stav časovaného čakania.

  • spať
  • pripojiť sa s časovým limitom
  • počkajte s časovým limitom
  • parkAž do
  • parkNanos
 public static final Thread.State TERMINATED 

Predstavuje konečný stav vlákna, ktoré je ukončené alebo mŕtve. Ukončené vlákno znamená, že dokončilo svoje vykonávanie.

Program Java na demonštráciu stavov vlákien

Nasledujúci program Java zobrazuje niektoré stavy vlákna definovaného vyššie.

Názov súboru: 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ýkon:

 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 

Vysvetlenie: Kedykoľvek vytvoríme nové vlákno, toto vlákno dosiahne nový stav. Keď je na vlákne vyvolaná metóda start(), plánovač vlákien presunie toto vlákno do spustiteľného stavu. Kedykoľvek je metóda join() vyvolaná na ľubovoľnej inštancii vlákna, aktuálne vlákno vykonávajúce tento príkaz musí počkať, kým toto vlákno dokončí svoje vykonávanie, t. j. presunúť toto vlákno do ukončeného stavu. Preto pred vytlačením konečného príkazu print na konzole program vyvolá metódu join() na vlákne t2, čím nechá vlákno t1 čakať, kým vlákno t2 dokončí svoje vykonávanie, a tak sa vlákno t2 dostane do ukončeného alebo mŕtveho stavu. . Vlákno t1 prejde do stavu čakania, pretože čaká, kým vlákno t2 dokončí svoje vykonávanie, pretože vyvolalo metódu join() na vlákne t2.