logo

Життєвий цикл потоку (стани потоку)

У Java потік завжди існує в одному з наступних станів. Ці стани:

  1. новий
  2. Активний
  3. Заблоковано / Очікування
  4. Час очікування
  5. Припинено

Пояснення різних станів потоку

новий: Щоразу, коли створюється новий потік, він завжди знаходиться в новому стані. Для потоку в новому стані код ще не був запущений і, отже, не розпочав своє виконання.

активний: Коли потік викликає метод start(), він переходить із нового стану в активний стан. Активний стан містить у собі два стани: один є запущений , а інший є біг .

    Запуск:Потік, який готовий до виконання, потім переміщується в стан, який можна виконувати. У запущеному стані потік може працювати або бути готовим до виконання в будь-який заданий момент часу. Обов’язком планувальника потоку є забезпечення часу виконання потоку, тобто переведення потоку в робочий стан.
    Програма, що реалізує багатопотоковість, отримує фіксований відрізок часу для кожного окремого потоку. Кожен потік виконується протягом короткого проміжку часу, і коли цей відрізок часу закінчується, потік добровільно віддає процесор іншому потоку, щоб інші потоки також могли працювати протягом свого відрізка часу. Щоразу, коли відбувається такий сценарій, усі ті потоки, які бажають запуститися, чекаючи своєї черги на запуск, перебувають у стані виконання. У запущеному стані існує черга, у якій лежать потоки.Запуск:Коли потік отримує центральний процесор, він переходить із стану runnable у запущений стан. Як правило, найпоширенішою зміною стану потоку є зміна з виконуваного на запущений і знову назад на виконуваний.

Заблоковано або очікує: Щоразу, коли потік неактивний протягом певного проміжку часу (не постійно), він або перебуває в заблокованому стані, або перебуває в стані очікування.

Наприклад, потік (скажімо, його ім'я 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 для представлення стану потоку. Ці константи:

що таке obj в java
 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.