logo

Жизнен цикъл на нишка (състояния на нишка)

В Java една нишка винаги съществува в някое от следните състояния. Тези състояния са:

  1. Нов
  2. Активен
  3. Блокиран/Изчакване
  4. Изчакване с време
  5. Прекратено

Обяснение на различни състояния на нишка

ново: Всеки път, когато се създава нова нишка, тя винаги е в новото състояние. За нишка в новото състояние кодът все още не е стартиран и следователно не е започнал своето изпълнение.

Активен: Когато една нишка извика метода start(), тя се премества от новото състояние в активното състояние. Активното състояние съдържа две състояния в себе си: едното е работещ , а другото е бягане .

    Работим:Нишка, която е готова за изпълнение, след това се премества в състояние за изпълнение. В състояние на изпълнение нишката може да работи или да е готова за изпълнение във всеки даден момент от време. Задължение на програмата за планиране на нишката е да осигури времето за изпълнение на нишката, т.е. преместването на нишката в състояние на изпълнение.
    Програма, прилагаща многопоточност, получава фиксиран отрязък от време за всяка отделна нишка. Всяка нишка работи за кратък период от време и когато този разпределен отрязък от време приключи, нишката доброволно отстъпва процесора на другата нишка, така че другите нишки също да могат да работят за своя отрязък от време. Всеки път, когато възникне такъв сценарий, всички тези нишки, които желаят да се изпълняват, чакащи реда си да се изпълняват, лежат в състояние на изпълнение. В състояние на изпълнение има опашка, където се намират нишките.Работи:Когато нишката получи процесора, тя се премества от състояние на изпълнение в състояние на изпълнение. Като цяло, най-честата промяна в състоянието на една нишка е от работеща към работеща и отново обратно към изпълняваща се.

Блокиран или изчакващ: Всеки път, когато дадена нишка е неактивна за определен период от време (не постоянно), тогава или нишката е в блокирано състояние, или е в състояние на изчакване.

Например нишка (да кажем, че името й е A) може да иска да отпечата някои данни от принтера. В същото време обаче другата нишка (да кажем, че името й е B) използва принтера, за да отпечата някои данни. Следователно нишка A трябва да изчака нишка B, за да използва принтера. По този начин нишка A е в блокирано състояние. Нишка в блокирано състояние не може да извърши каквото и да е изпълнение и по този начин никога да не консумира цикъл на централния процесор (CPU). Следователно можем да кажем, че нишка A остава неактивна, докато планировчикът на нишки не активира отново нишка A, която е в състояние на изчакване или блокиране.

Когато основната нишка извика метода join(), се казва, че основната нишка е в състояние на изчакване. След това основната нишка изчаква дъщерните нишки да изпълнят задачите си. Когато дъщерните нишки завършат работата си, се изпраща известие до основната нишка, което отново премества нишката от чакащо в активно състояние.

Ако има много нишки в изчакващо или блокирано състояние, тогава е задължение на планировчика на нишки да определи коя нишка да избере и коя да отхвърли, след което на избраната нишка се дава възможност да се изпълни.

Време на изчакване: Понякога чакането води до глад. Например нишка (нейното име е A) е влязла в критичната секция на код и не желае да напусне тази критична секция. При такъв сценарий друга нишка (името й е B) трябва да чака вечно, което води до глад. За да се избегне такъв сценарий, на нишката B се дава времево състояние на изчакване. По този начин нишката е в състояние на изчакване за определен период от време, а не завинаги. Истински пример за изчакване с време е, когато извикаме метода sleep() на конкретна нишка. Методът sleep() поставя нишката в състояние на изчакване с време. След като времето изтече, нишката се събужда и започва изпълнението си от момента, в който е напуснала по-рано.

Прекратено: Нишката достига състояние на прекратяване поради следните причини:

  • Когато една нишка приключи работата си, тогава тя съществува или прекратява нормално.
  • Ненормално прекратяване:Това се случва при някои необичайни събития, като необработено изключение или грешка в сегментирането.

Прекратена нишка означава, че нишката вече не е в системата. С други думи, нишката е мъртва и няма начин да се възроди (активна след унищожаване) мъртвата нишка.

Следващата диаграма показва различните състояния, участващи в жизнения цикъл на една нишка.

Жизнен цикъл на Java нишка

Внедряване на състояния на нишки

В Java можете да получите текущото състояние на нишка, като използвате Thread.getState() метод. The java.lang.Thread.State класът на Java предоставя константите ENUM за представяне на състоянието на нишка. Тези константи са:

тримесечие в бизнеса
 public static final Thread.State NEW 

Той представлява първото състояние на нишка, което е НОВО състояние.

 public static final Thread.State RUNNABLE 

Той представлява състоянието, което може да се изпълнява. Това означава, че нишка чака в опашката за изпълнение.

 public static final Thread.State BLOCKED 

Представлява блокираното състояние. В това състояние нишката чака да получи заключване.

 public static final Thread.State WAITING 

Представлява състоянието на изчакване. Нишка ще премине в това състояние, когато извика метода Object.wait() или метода Thread.join() без изчакване. Нишка в състояние на изчакване чака друга нишка да изпълни задачата си.

 public static final Thread.State TIMED_WAITING 

Той представлява времето на изчакване. Основната разлика между изчакване и изчакване във времето е ограничението във времето. Изчакването няма ограничение във времето, докато изчакването с ограничено време има ограничение във времето. Нишка, извикваща следния метод, достига състоянието на изчакване във времето.

  • сън
  • присъединете се с таймаут
  • изчакайте с таймаут
  • parkUntil
  • паркНанос
 public static final Thread.State TERMINATED 

Той представлява крайното състояние на нишка, която е прекратена или мъртва. Прекратена нишка означава, че е завършила своето изпълнение.

Java програма за демонстриране на състояния на нишки

Следната програма на Java показва някои от състоянията на нишка, дефинирана по-горе.

Име на файл: 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()); } } 

Изход:

 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 

Обяснение: Всеки път, когато създадем нова нишка, тази нишка достига новото състояние. Когато методът start() се извика в нишка, планировчикът на нишки премества тази нишка в състояние на изпълнение. Всеки път, когато методът join() се извика на който и да е екземпляр на нишка, текущата нишка, изпълняваща този оператор, трябва да изчака тази нишка да завърши своето изпълнение, т.е. да премести тази нишка в прекратено състояние. Следователно, преди окончателният оператор за печат да бъде отпечатан на конзолата, програмата извиква метода join() на нишка t2, карайки нишката t1 да изчака, докато нишката t2 завърши своето изпълнение и по този начин нишката t2 стига до прекратено или мъртво състояние . Нишката t1 преминава в състояние на изчакване, защото изчаква нишка t2 да завърши изпълнението си, тъй като е извикала метода join() на нишка t2.