Жизненный цикл и состояния потоков Java

В Java поток — это облегченный процесс, который позволяет программе работать более эффективно, запуская несколько потоков параллельно. Внутри себя JVM создает поток и передает его операционной системе для выполнения. Затем операционная система планирует, выполняет этот поток и выполняет различные переходы состояний между несколькими потоками.

Во время переходов состояний и жизненного цикла поток переходит в различные состояния в зависимости от нескольких факторов, таких как приоритет потока, принудительная приостановка потока или ожидание вывода блокирующих операций.

1. Состояния жизненного цикла потока

Поток Java может находиться в любом из следующих состояний в течение своего жизненного цикла:

  • Новый
  • Запускаемый(или работающий)
  • Заблокировано
  • Ожидающий
  • Ожидание по времени
  • Прекращено

Их также называют событиями жизненного цикла потока. Давайте разберем каждое состояние более подробно.

Жизненный цикл и состояния потоков Java0

1.1.Новый

Как только вы создаете новый поток, он находится в состоянии NEW. Поток остается в состоянии New, пока программа не запустит поток с помощью своего метода start(). В этот момент поток не активен.

Thread thread = new Thread();System.out.println(thread.getState()); //NEW

1.2.Работающий

Вызов метода thread.start() переводит поток в состояние RUNNABLE. В этот момент управление выполнением передается планировщику потоков ОС для завершения его выполнения. С этого момента планировщик потоков решает, следует ли выполнить этот поток(это также известно как диспетчеризация потока) или его следует приостановить, чтобы дать шанс другим готовым к выполнению потокам. Планирование потоков зависит от платформы — поведение многопоточной программы может различаться в разных реализациях Java.

В большинстве операционных систем каждому потоку выделяется небольшой объем процессорного времени — называемый квантом или квантом времени — для выполнения своей задачи. Задача, использующая свой квант, называется находящейся в состоянии RUNNING. Когда ее квант истекает, поток возвращается в состояние RUNNABLE, и операционная система назначает процессору другой поток.

Процесс, который операционная система использует для определения того, какой поток следует отправить, называется планированием потоков и зависит от приоритетов потоков.

Thread thread = new Thread();thread.start();System.out.println(thread.getState()); //RUNNABLE

Операционная система скрывает состояния RUNNABLE и RUNNING от виртуальной машины Java(JVM), которая видит только состояние RUNNABLE.

БЕГУЩИЙ VS БЕГУЩИЙ

1.3 Заблокировано

Готовый к выполнению поток переходит в состояние ЗАБЛОКИРОВАН, когда он пытается выполнить задачу, которая не может быть завершена немедленно, и он должен временно подождать, пока эта задача не будет завершена.

Например, когда поток выдает запрос ввода/вывода, операционная система блокирует выполнение потока до тех пор, пока этот запрос ввода/вывода не завершится — в этот момент заблокированный поток переходит в состояние RUNNABLE, чтобы он мог возобновить выполнение. Заблокированный поток не может использовать процессор, даже если он доступен.

1.4 Ожидание

Обычно программа переводит поток в состояние WAIT, потому что что-то еще должно быть сделано до того, что делает текущий поток. Поток можно перевести в состояние ожидания, используя

  • объект.wait()
  • thread.join() или
  • LockSupport.парк()

После завершения состояния ожидания потока его состояние изменяется на RUNNABLE, и он перемещается обратно в пул потоков.

1.5. Ожидание по времени

RUNNABLE поток может перейти в состояние TIMED WAITING, если он предоставляет необязательный интервал ожидания, когда он ждет, пока другой поток выполнит задачу. Вы можете перевести поток Java в состояние TIMED WAITING, вызвав следующие методы:

  • thread.sleep(длинный миллис)
  • wait(int timeout) или wait(int timeout, int nanos)
  • thread.join(длинный миллис)

Такой поток возвращается в состояние RUNNABLE, когда он уведомлен другим потоком или когда истекает временной интервал — в зависимости от того, что наступит раньше. Временно ожидающие потоки и ожидающие потоки не могут использовать процессор, даже если он доступен.

1.6. Прекращено

Поток переходит в состояние TERMINATED(иногда называемое мертвым состоянием), когда он успешно завершает свою задачу или иным образом завершается из-за какой-либо ошибки или даже был принудительно завершен.

2. Тупик и голод

Пожалуйста, помните, что хотя планировщик потоков JVM и ОС делает все возможное, иногда потоки могут вызывать зависание или взаимоблокировку.

Взаимная блокировка происходит, когда ожидающий поток(назовем его thread1) не может продолжить работу, поскольку он ждет(прямо или косвенно) продолжения работы другого потока(назовем его thread2). И одновременно поток thread2 не может продолжить работу, поскольку он ждет(прямо или косвенно) продолжения работы thread1.

3. Заключение

В этом руководстве по параллелизму Java мы узнали о жизненном цикле потока в Java и о том, как происходят переходы между различными состояниями потока.

Прокрутить вверх