logo

Egy szál életciklusa (szál állapotok)

Java nyelven egy szál mindig létezik a következő állapotok bármelyikében. Ezek az állapotok a következők:

  1. Új
  2. Aktív
  3. Blokkolt / Várakozás
  4. Időzített várakozás
  5. Megszűnt

A különböző szálállapotok magyarázata

Új: Amikor új szál jön létre, az mindig új állapotban van. Egy új állapotú szál esetében a kód még nem futott le, így még nem indult el a végrehajtása.

Aktív: Amikor egy szál meghívja a start() metódust, az új állapotból az aktív állapotba lép. Az aktív állapot két állapotot tartalmaz benne: az egyik az futtatható , a másik pedig az futás .

    Futtatható:A futásra kész szál ezután futtatható állapotba kerül. Futtatható állapotban a szál futhat vagy készen állhat a futtatásra bármely adott pillanatban. A szálütemező feladata, hogy biztosítsa a szál futásához szükséges időt, azaz a szálat futó állapotba helyezze.
    A többszálas működést megvalósító program minden egyes szálhoz fix időszeletet szerez. Minden egyes szál rövid ideig fut, és amikor a lefoglalt időszelet véget ér, a szál önként adja át a CPU-t a másik szálnak, így a többi szál is futni tud a saját idejére. Valahányszor előfordul egy ilyen forgatókönyv, mindazok a szálak, amelyek hajlandóak futni, és arra várnak, hogy futhassanak, futtatható állapotban vannak. Futtatható állapotban van egy sor, ahol a szálak fekszenek.Futás:Amikor a szál megkapja a CPU-t, a futtatható állapotból a futó állapotba kerül. Általánosságban elmondható, hogy a szál állapotának leggyakoribb változása a futtathatóról a futásra, majd ismét a futtathatóra való visszalépés.

Letiltva vagy várakozva: Amikor egy szál egy ideig inaktív (nem tartósan), akkor a szál vagy blokkolt vagy várakozási állapotban van.

Például egy szál (tegyük fel, hogy A neve) ki akar nyomtatni bizonyos adatokat a nyomtatóról. Ugyanakkor a másik szál (mondjuk a neve B) a nyomtatót használja bizonyos adatok nyomtatására. Ezért az A szálnak meg kell várnia, amíg a B szál használni tudja a nyomtatót. Így az A szál blokkolt állapotban van. A blokkolt állapotban lévő szál nem tud semmilyen végrehajtást végrehajtani, és így soha nem használja fel a központi feldolgozó egység (CPU) egyetlen ciklusát sem. Ezért azt mondhatjuk, hogy az A szál tétlen marad mindaddig, amíg a szálütemező újra nem aktiválja az A szálat, amely várakozó vagy blokkolt állapotban van.

Amikor a főszál meghívja a join() metódust, akkor azt mondják, hogy a főszál várakozó állapotban van. A főszál ezután arra vár, hogy a gyermekszálak befejezzék a feladataikat. Amikor az alárendelt szálak befejezik a feladatukat, értesítést küldenek a fő szálnak, amely ismét áthelyezi a szálat a várakozásból az aktív állapotba.

Ha sok szál van várakozó vagy blokkolt állapotban, akkor a szálütemező feladata meghatározni, hogy melyik szálat válassza és melyiket utasítsa el, majd a kiválasztott szál lehetőséget kap a futásra.

Időzített várakozás: Néha a várakozás éhezéshez vezet. Például egy szál (a neve A) belépett egy kód kritikus szakaszába, és nem hajlandó elhagyni azt. Ilyen esetben egy másik szálnak (a neve B) örökké várnia kell, ami éhezéshez vezet. Az ilyen forgatókönyvek elkerülése érdekében a B szál időzített várakozási állapotot kap. Így a szál egy meghatározott időtartamig van várakozási állapotban, és nem örökké. Az időzített várakozás igazi példája, amikor egy adott szálon meghívjuk a sleep() metódust. A sleep() metódus a szálat időzített várakozási állapotba helyezi. Az idő lejárta után a szál felébred, és onnan kezdi a végrehajtást, amikor korábban elment.

Megszűnt: Egy szál a következő okok miatt éri el a befejezési állapotot:

  • Amikor egy szál befejezte a feladatát, akkor a szokásos módon létezik vagy megszűnik.
  • Rendellenes befejezés:Ez akkor fordul elő, amikor néhány szokatlan esemény, például egy kezeletlen kivétel vagy szegmentációs hiba.

A befejezett szál azt jelenti, hogy a szál már nincs a rendszerben. Más szóval, a szál halott, és nincs mód arra, hogy az elhalt szálat újra létrejöjjön (aktív a kill után).

A következő diagram a szál életciklusában részt vevő különböző állapotokat mutatja be.

Java szál életciklusa

A szálállapotok megvalósítása

Java-ban a szál aktuális állapotát a következővel lehet lekérni Thread.getState() módszer. A java.lang.Thread.State A Java osztálya biztosítja az ENUM konstansokat, amelyek a szál állapotát jelzik. Ezek az állandók a következők:

linkedlist java
 public static final Thread.State NEW 

Ez egy szál első állapotát jelenti, amely az ÚJ állapot.

 public static final Thread.State RUNNABLE 

Ez a futtatható állapotot jelenti. Azt jelenti, hogy egy szál a sorban várakozik a futásra.

 public static final Thread.State BLOCKED 

Ez a blokkolt állapotot jelenti. Ebben az állapotban a szál zárolásra vár.

 public static final Thread.State WAITING 

A várakozás állapotát jelképezi. Egy szál ebbe az állapotba kerül, ha meghívja az Object.wait() metódust, vagy a Thread.join() metódust időtúllépés nélkül. Egy várakozó állapotban lévő szál arra vár, hogy egy másik szál befejezze a feladatát.

 public static final Thread.State TIMED_WAITING 

Az időzített várakozási állapotot jelenti. A fő különbség a várakozás és az időzített várakozás között az időkorlát. A várakozásnak nincs időkorlátja, míg az időzített várakozásnak időkorlátja van. A következő metódust hívó szál eléri az időzített várakozási állapotot.

  • alvás
  • csatlakozzon időtúllépéssel
  • várjon időtúllépéssel
  • park Amíg
  • parkNanos
 public static final Thread.State TERMINATED 

A befejezett vagy halott szál végső állapotát jelenti. A befejezett szál azt jelenti, hogy befejezte a végrehajtását.

Java program szálállapotok demonstrálására

A következő Java program egy fent meghatározott szál néhány állapotát mutatja be.

Fájl név: 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()); } } 

Kimenet:

 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 

Magyarázat: Amikor új szálat indítunk, az új állapotot ér el. Amikor a start() metódus meghívásra kerül egy szálon, a szálütemező a szálat futtatható állapotba helyezi át. Amikor a join() metódus meghívásra kerül bármely szálpéldányon, az utasítást végrehajtó aktuális szálnak meg kell várnia, amíg ez a szál befejezi a végrehajtását, azaz a szálat a befejezett állapotba helyezi. Ezért a végső print utasítás kinyomtatása előtt a program meghívja a join() metódust a t2 szálon, így a t1 szál megvárja, míg a t2 szál befejezi a végrehajtást, és így a t2 szál befejezett vagy holt állapotba kerül. . A t1 szál várakozási állapotba kerül, mert arra vár, hogy a t2 szál befejezze a végrehajtását, mivel meghívta a join() metódust a t2 szálon.