— Привет, Амиго!
Мы начинаем новую тему – работа с нитями или как их еще называют – трэдами (от 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 и будет ждать освобождения объекта-мютекса.
Вот как выглядит эта ситуация с состояниями:
Но и это еще не все. Есть еще отдельное состояние, когда нить не blocked, но и не ready – это waiting. Например, при вызове методов join() у другой нити.
При вызове join() у объекта другой нити, наша нить как-бы «присоединяется к ней», а на деле – просто ждет ее завершения.
Кроме того, есть еще метод wait(), (из набора wait, notify, notifyAll), вызов которого тоже переводит нить в состояние waiting.
— Ничего себе.
— Подожди! Но и это еще не все. Нить может спать, например, при вызове метода sleep. Для этого тоже есть отдельное состояние «timed waiting». «timed waiting» значит, что нить чего-то ждет ограниченное время. Если вызвать метод wait с параметром — wait(timeout) или join(timeout), то нить перейдет в состояние timed waiting.
Так что вот тебе полная схема:
— Гм. Это все? Или там есть еще 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 очень любят спрашивать на собеседованиях.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
CircleCycle