logo

Cicle de vida d'un fil (estats del fil)

A Java, un fil sempre existeix en qualsevol dels estats següents. Aquests estats són:

  1. Nou
  2. Actiu
  3. Bloquejat / Esperant
  4. Espera cronometrada
  5. Terminat

Explicació dels diferents estats de fil

Nou: Sempre que es crea un fil nou, sempre es troba en el nou estat. Per a un fil en el nou estat, el codi encara no s'ha executat i, per tant, no ha començat la seva execució.

Actiu: Quan un fil invoca el mètode start(), passa del nou estat a l'estat actiu. L'estat actiu conté dos estats al seu interior: un és executable , i l'altre és corrent .

    Es pot executar:Un fil que està a punt per executar-se es mou a l'estat executable. En l'estat d'execució, el fil pot estar en execució o pot estar llest per executar-se en un moment determinat. És el deure del programador de fils proporcionar el temps d'execució del fil, és a dir, moure el fil a l'estat d'execució.
    Un programa que implementa multithreading adquireix un període fix de temps per a cada fil individual. Tots i cadascun dels fils s'executen durant un breu període de temps i, quan s'acaba aquest període de temps assignat, el fil cedeix voluntàriament la CPU a l'altre fil, de manera que els altres fils també es poden executar durant el seu període de temps. Sempre que es produeix un escenari així, tots aquells fils que estan disposats a executar-se, esperant el seu torn, es troben en estat executable. En l'estat executable, hi ha una cua on es troben els fils.Córrer:Quan el fil aconsegueix la CPU, passa de l'estat d'execució a l'estat d'execució. En general, el canvi més comú en l'estat d'un fil és de executable a executable i de nou a executable.

Bloquejat o esperant: Sempre que un fil està inactiu durant un període de temps (no permanentment), llavors el fil està en estat bloquejat o en estat d'espera.

Per exemple, un fil (diguem que el seu nom és A) pot voler imprimir algunes dades de la impressora. Tanmateix, al mateix temps, l'altre fil (diguem que es diu B) està utilitzant la impressora per imprimir algunes dades. Per tant, el fil A ha d'esperar que el fil B utilitzi la impressora. Així, el fil A es troba en estat bloquejat. Un fil en estat bloquejat no pot realitzar cap execució i, per tant, mai consumeix cap cicle de la Unitat Central de Processament (CPU). Per tant, podem dir que el fil A roman inactiu fins que el planificador de fils reactiva el fil A, que es troba en estat d'espera o bloquejat.

Quan el fil principal invoca el mètode join(), es diu que el fil principal està en estat d'espera. Aleshores, el fil principal espera que els fils secundaris completin les seves tasques. Quan els fils secundaris completen la seva feina, s'envia una notificació al fil principal, que torna a moure el fil d'espera a l'estat actiu.

Si hi ha molts fils en estat d'espera o bloquejat, és el deure del planificador de fils determinar quin fil triar i quin rebutjar, i el fil escollit té l'oportunitat d'executar-se.

Espera cronometrada: De vegades, l'espera porta a la fam. Per exemple, un fil (el seu nom és A) ha entrat a la secció crítica d'un codi i no està disposat a sortir d'aquesta secció crítica. En aquest escenari, un altre fil (el seu nom és B) ha d'esperar per sempre, el que porta a la fam. Per evitar aquest escenari, es dóna un estat d'espera cronometrat al fil B. Per tant, el fil es troba en l'estat d'espera durant un període de temps específic, i no per sempre. Un exemple real d'espera cronometrada és quan invoquem el mètode sleep() en un fil específic. El mètode sleep() posa el fil en l'estat d'espera cronometrada. Un cop acabat el temps, el fil es desperta i comença la seva execució des de quan ha sortit abans.

Finalitzat: Un fil arriba a l'estat de terminació pels motius següents:

  • Quan un fil ha acabat la seva feina, llavors existeix o finalitza normalment.
  • Terminació anormal:Es produeix quan hi ha esdeveniments inusuals, com ara una excepció no gestionada o un error de segmentació.

Un fil finalitzat significa que el fil ja no és al sistema. En altres paraules, el fil està mort i no hi ha manera que ningú pugui reaparecer (actiu després de matar) el fil mort.

El diagrama següent mostra els diferents estats implicats en el cicle de vida d'un fil.

Cicle de vida del fil Java

Implementació d'estats de fil

A Java, es pot obtenir l'estat actual d'un fil utilitzant el Thread.getState() mètode. El java.lang.Thread.Estat La classe de Java proporciona les constants ENUM per representar l'estat d'un fil. Aquestes constants són:

ordenant la llista en java
 public static final Thread.State NEW 

Representa el primer estat d'un fil que és l'estat NOU.

 public static final Thread.State RUNNABLE 

Representa l'estat que es pot executar. Significa que un fil està esperant a la cua per executar-se.

 public static final Thread.State BLOCKED 

Representa l'estat bloquejat. En aquest estat, el fil està esperant per adquirir un bloqueig.

 public static final Thread.State WAITING 

Representa l'estat d'espera. Un fil passarà a aquest estat quan invoqui el mètode Object.wait() o el mètode Thread.join() sense temps d'espera. Un fil en estat d'espera està esperant que un altre fil completi la seva tasca.

 public static final Thread.State TIMED_WAITING 

Representa l'estat d'espera cronometrat. La principal diferència entre l'espera i l'espera cronometrada és la limitació de temps. L'espera no té cap limitació de temps, mentre que l'espera cronometrada té la limitació de temps. Un fil que invoca el mètode següent arriba a l'estat d'espera cronometrada.

  • dormir
  • uneix-te amb el temps d'espera
  • esperar amb temps d'espera
  • parcFins
  • parkNanos
 public static final Thread.State TERMINATED 

Representa l'estat final d'un fil que està acabat o mort. Un fil finalitzat significa que ha completat la seva execució.

Programa Java per a la demostració d'estats de fil

El següent programa Java mostra alguns dels estats d'un fil definit anteriorment.

Nom de l'arxiu: 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()); } } 

Sortida:

 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 

Explicació: Sempre que generem un fil nou, aquest assoleix el nou estat. Quan s'invoca el mètode start() en un fil, el planificador de fils mou aquest fil a l'estat executable. Sempre que s'invoca el mètode join() en qualsevol instància del fil, el fil actual que executa aquesta instrucció ha d'esperar que aquest fil acabi la seva execució, és a dir, mou aquest fil a l'estat final. Per tant, abans que la sentència d'impressió final s'imprimeixi a la consola, el programa invoca el mètode join() al fil t2, fent que el fil t1 espere mentre el fil t2 acaba la seva execució i, per tant, el fil t2 arriba a l'estat final o mort. . El fil t1 passa a l'estat d'espera perquè està esperant que el fil t2 acabi la seva execució, ja que ha invocat el mètode join() al fil t2.