Наконец-то ясно объяснен переход шести состояний потока!

Java



Когда мы соприкасаемся с программированием, мы начинаем соприкасаться с различными жизненными циклами, такими как жизненный цикл объектов, жизненный цикл программ и т. д. Для потоков тоже есть свой жизненный цикл, и это также необходимо для собеседований и наших в -глубокое понимание многопоточности, сегодня мы в основном знакомимся с жизненным циклом потоков и переходами различных состояний.

Шесть состояний потока

Жизненный цикл потока в основном имеет следующие шесть состояний:

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


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

Новый Новый штат

  • Прежде всего, мы покажем блок-схему перехода всего состояния потока.Далее мы дадим подробное введение и объяснение.Как показано на рисунке ниже, мы можем интуитивно увидеть переход шести состояний.Прежде всего, верхний левый этоNEWсостояние, в котором создается новый поток, эквивалентное нашемуnew Thread()процесс.

  • New Указывает состояние, в котором поток создан, но еще не запущен: когда мы используемnew Thread() При создании нового потока, если поток еще не запущенstart()метод, то поток не начинает выполнятьсяrun() код в методе, то его состояниеNew. И как только поток вызововstart(), его состояние изменится сNew статьRunnableВведите зеленую коробку на рисунке

Родительское родительское состояние

  • Java середина**Runable **Состояние соответствует двум состояниям в состоянии потока операционной системы, которыеRunning иReady, это,Javaв центреRunnableсостояние потокаЕго можно исполнить, а можно и не реализовать., ожидая выделения ресурсов ЦП.

  • Итак, если запущенный потокRunnableсостояние, когда он выполняется на полпути к выполнению задачи, выполнить потокCPUПланируется выполнение других действий, из-за чего поток временно не запускается, его состояние остается неизменным илиRunnable, потому что его можно запланировать обратно, чтобы продолжить выполнение задачи в любое время.



**Заблокировано**
  • Ключевое состояние потока распознается вышеRunnable, то давайте взглянем на следующие три состояния, которые мы можем все вместе назвать состоянием блокировки.Blocked(被阻塞),Waiting(等待),Timed Waiting(计时等待) .

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

  • Сначала давайте познакомимсяBlockedсостояние, которое является относительно простым состоянием, как мы можем видеть на диаграмме ниже, отRunnableГосударственная записьBlockedЕсть только один путь в состояние, и это при входеsynchronizedне удалось получить соответствующийmonitorзамок (оmonitorМы введем замок позже, здесь мы знаемsynchronizedреализация основана наmonitorЗамок),


  • Справа мы видим, что есть соединительные линии отBlockedстатус указывает наRunnable, и тут только один случай, тогда когда нить попадетmonitorзамок, нить войдетRunnableучастие в телеCPUразграбление ресурсов

Состояние ожидания


Мы видели состояние блокировки выше, тогда давайте посмотримWaitingстатус, дляWaitingЕсть три ситуации для входа в состояние, как показано на следующем рисунке:

  • Когда поток вызывается без установкиTimeoutпараметрическийObject.wait()метод
  • Когда вызовы потока не установленыTimeoutпараметрическийThread.join()метод
  • Когда поток вызываетLockSupport.park()метод

Waiting 等待状态

оLockSupport.park()метод, давайте поговорим об этом здесь, мы знаем из вышеизложенногоBlockedнаправлен наsynchronized monitorзаблокирован, но вJavaНа самом деле есть много других замков, таких какReentrantLockи т. д. В этих блокировках, если поток не получит блокировку, он войдет напрямуюWaitingгосударство, по сути, это по сути казньLockSupport.park()метод введенWaitingгосударство

  • **Blocked **и**Waiting**Разница
    • Blockedожидает освобождения других потоковmonitorЗамок
    • Waitingожидает условия, напримерjoinпоток завершил выполнение, илиnotify()/notifyAll() .

Ожидание по времени Состояние ожидания по времени

  • Наконец, давайте поговорим об этомTimed Waitingсостояние, которое связано сWaitingСостояния очень похожи, единственная разница в том, есть ли ограничение по времени, вTimed WaitingВ состоянии он будет ждать тайм-аут, а затем проснется системой, или его также можно разбудить с помощью предварительного уведомления, напримерnotify



Из приведенного выше рисунка видно, что поток войдет в следующих случаяхTimed Waiting государство.

  • Поток выполняет заданные параметры времени Thread.sleep(long millis)метод;
  • Поток выполняет набор параметров времениObject.wait(long timeout)метод;
  • Поток выполняет набор параметров времениThread.join(long millis)метод;
  • Поток выполняет набор параметров времениLockSupport.parkNanos(long nanos)Методы иLockSupport.parkUntil(long deadline)метод.

Благодаря этому мы можем далее видеть, что это то же самое, что и состояние ожидания.

переход между состояниями потока

Выше мы говорили о характеристиках их соответствующих состояний и о ситуации, при которой состояние выполнения переходит в соответствующее состояние, далее разберем переход между соответствующими состояниями в дальнейшем, собственно, главноеBlocked,waiting,Timed WaitingПереходы трех состояний и то, как они входят в следующее состояние и, наконец, входятRunnable

Blocked ВходитьRunnable

  • хочу отBlockedгосударственная запись RunnableГосударство, мы сказали выше, что нить должна быть полученаmonitorБлокировка, но если вы хотите войти в другие состояния, она относительно особенная, потому что у нее нет механизма тайм-аута, то есть она не будет активно входить.

Как показано на следующем рисунке, линии выделены жирным фиолетовым цветом:


WaitingВходитьRunnable

  • Только при выполнении LockSupport.unpark(),или joinВыполнение потока заканчивается или может начаться, когда оно прерваноRunnableгосударство.
  • Обозначено, как показано ниже


  • Если вызывается другим потокомnotify()илиnotifyAll()чтобы разбудить его, он идет прямо кBlockedСтатус, здесь могут быть вопросы, напрямую не входитьRunnable? Здесь нужно обратить внимание на одну вещь, потому что проснисьWaitingПоток потока, если он вызываетсяnotify()илиnotifyAll(), необходимо сначала провестиmonitorзамок, вот о чем мы говоримwait(),notifyДолжен бытьsynchronizedв кодовом блоке.
  • так вWaitingЕсли поток в состоянии не может получить блокировку при пробуждении, он войдет вBlockedсостояние до выполненияnotify()/notifyAll()Пробуждающий его поток завершает выполнение и освобождаетmonitorЗамок, вы можете обратиться к нему, чтобы схватить этот замок, если он может захватить, это будетBlockedстатус назадRunnableгосударство.

Все должны обратить внимание на этот момент здесь, Когда мы просыпаемся через уведомление, мы сначала войдем в состояние блокировки, а затем мы войдем в состояние Runnable после того, как схватимся за горло блокировки монитора!



** «Временное ожидание» переходит в «Runnable» **
  • Также вTimed Waitingвыполнить вnotify()иnotifyAll() То же верно, они войдут первымиBlockedсостояние, а затем после успешного захвата блокировки вернуться кRunnableгосударство.


  • Но для ожидания по времени у него есть механизм тайм-аута, то есть, если время тайм-аута истекает, система автоматически получит блокировку напрямую или когдаjoinВыполнение потока завершается/вызываетсяLockSupport.unpark()/ прерывается и т. д. будет напрямую входитьRunnableсостояние, не переживаяBlockedгосударство


Прекращено


Наконец, давайте поговорим о последнем состоянии,TerminatedСостояние прекращения, чтобы войти в это состояние, есть две возможности.

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

Суммировать

Напоследок поговорим о двух моментах, на которые необходимо обратить внимание при взгляде на процесс преобразования потоков:

  • Состояние потока находится в направлении стрелки, например, поток начинается сNew Статус не доступен напрямуюBlockedсостояние, оно должно пройти сначалаRunnableгосударство.

  • Жизненный цикл потока необратим: После входаRunnableсостояние не может быть возвращеноNewсостояние; после завершения дальнейшие изменения состояния невозможны.

  • Таким образом, поток может иметь только одинNew иTerminated состоянии и могут быть преобразованы друг в друга только в том случае, если они находятся в промежуточном состоянии. То есть эти два состояния не будут участвовать во взаимной трансформации.



Эта статья опубликована AnonyStar и может быть воспроизведена с указанием первоисточника.
Добро пожаловать в публичный аккаунт WeChat: шорткод Yunqi для получения более качественных статей
Для получения дополнительных статей обратите внимание на блог автора:Короткий код Yunqi i-code.online