Thread Life Circle, стан об'єкта Thread - 1

— Привіт, Аміго!

Ми розпочинаємо нову тему – робота з нитками або як їх ще називають – едамами (від thread).

— А я чув, що треди називають потоками.

— Так, така назва все ще вживається, але поступово виходить із моди. Проблема в тому, що ще є stream, який дослівно перекладається як «потік». Тому thread'и прийнято називати нитками (дослівний переклад) чи програмними потоками. На противагу stream'ам, які називають потоками введення-виведення.

Отже. Сьогодні ми розглянемо стан об'єкта Thread, через який він проходить (або може проходити) у процесі роботи нитки.

Скільки станів ти можеш назвати прямо зараз, Аміго?

— Два. Перше – це нитка до виклику методу start(): об'єкт є, але нитка ще активна. І друге — після виклику методу start() – коли нитка щось робить, важливе.

— Ти маєш рацію, таке розмежування є, ці стани називаються new і running, але це лише початок.

По-перше, нитка колись закінчує роботу, а значить, може бути така ситуація - об'єкт Thread є, але нитка не в змозі new і не в змозі running. Такий стан, коли нитка завершила роботу, називається terminated.

Але це ще не все. Не варто забувати, що у кожний момент часу працює лише одна нитка. А видима одночасна робота – це постійне перескакування процесора з нитки на нитку. Для часу, коли нитка ніби працює, а насправді чекає на свою чергу, теж є окремий стан. Воно називається ready-to-run. Нитка під час роботи постійно змінює стан з running на ready і потім знову на running, коли стає активною.

Відразу після виклику методу start() нитка отримує статус ready-to-run, і поміщається до загального списку ниток, між якими перемикається Java-машина.

>

— Не так уже й складно. До початку роботи стан new, після закінчення - terminated. А в процесі роботи нитка знаходиться то в активному (running), то в пасивному (ready) режимі роботи.

— Твоя стислість дивує, але так і є.

Але це ще не все. Нитка може бути заблокована. Наприклад, під час входу в блок synchronized. Нитка підійшла до блоку коду, позначеного synchronized, а він зайнятий іншою ниткою. Тоді наша нитка отримає стан blocked і чекатиме на звільнення об'єкта-мютексу.

Ось як виглядає ця ситуація зі станами:

Thread Life Circle, стан об'єкта Thread - 2

Але це ще не все. Є ще окремий стан, коли нитка не blocked, але і не ready - це waiting. Наприклад, при викликі методів join() в іншій нитці.

При виклику join() у об'єкта іншої нитки, наша нитка як би «приєднується до неї», а насправді – просто чекає на її завершення.

Крім того, є ще метод wait(), (з набору wait, notify, notifyAll), виклик якого теж переводить нитку в стан waiting.

— Нічого собі.

— Почекай! Але це ще не все. Нитка може спати, наприклад, під час виклику методу sleep. Для цього є окремий стан «timed waiting». "timed waiting" означає, що нитка чогось чекає обмежений час. Якщо викликати метод wait із параметром — wait(timeout) або join(timeout), то нитка перейде в стан timed waiting.

Тож ось тобі повна схема:

Thread Life Circle, стан об'єкта Thread - 3

— Гм. Це все? Чи є там ще 10 нових цікавих станів?

— Поки що – все.

Насправді – можеш запам'ятати лише першу схему – вона простіша. Але друга точніша.

Як не дивно – в інтернеті дуже багато схем станів Thread і всі вони різні.

Тому я і навела тобі цю схему – вона найповніша і найправильніша.

На цій схемі стану ready та running об'єднані в єдиний блок – runnable, і знаєш чому?

— Ні. Я ж уперше це все бачу взагалі.

— Клас Thread має внутрішній клас State, а також метод public State getState().

Приклад
public enum State
{
 NEW,
 RUNNABLE,
 BLOCKED,
 WAITING,
 TIMED_WAITING,
 TERMINATED;
}

Ти завжди можеш викликати у об'єкта типу Thread метод getState() і дізнатися про його поточний стан. І, звичайно, воно буде одним із значень enum State.

— Зрозуміло. Тобто справжні стани всередині Java-машини, а є стани, які можна отримати з Java-коду за допомогою методу State getState().

А в яких ситуаціях я буду це використовувати?

— Швидше за все – у жодних.

Але знати про те, що відбувається при роботі всередині нитки, ти зобов'язаний. Інакше на твоєму шляху буде багато помилок, і ти навіть не здогадуватимешся про їхню причину.

Крім того, стани Thread дуже люблять запитувати на співбесідах.