Статьи по Java

Состояния потоков в Java

Состояние потоков – распространенный вопрос на собеседовании при приеме на работу, связанную с многопоточностью.

В Java потоки могут находиться в шести состояниях.

Каждому изменению состояния предшествует какое-то событие.

Что это за события? Приглашаю вас в пост, чтобы узнать!

Состояние

Для получения состояния потока мы используем встроенный метод getState(), находящийся в классе Thread:

final Thread newThread = new Thread(); newThread.getState();
Code language: PHP (php)

Как я уже писал во введении, поток может находиться в одном из шести состояний:

NEW

Поток находится в состоянии NEW сразу после его создания. Он сохраняет это состояние до тех пор, пока мы не выполним метод start():

@Test void shouldReturnNewState() { // Given final Thread newThread = new Thread(); // Then assertThat(newThread.getState()).isEqualTo(Thread.State.NEW); }
Code language: PHP (php)

RUNNABLE

Когда метод start() вызывается для потока, он изменяет свое состояние с NEW на RUNNABLE:

@Test void shouldReturnRunnableState() throws InterruptedException { // Given final Thread runnableThread = new Thread(() -> { assertThat(Thread.currentThread().getState()).isEqualTo(Thread.State.RUNNABLE); }); // When runnableThread.start(); runnableThread.join(); }
Code language: JavaScript (javascript)

BLOCKED

Поток в состоянии BLOCKED можно найти, если доступ к критической секции в данный момент занят (есть блокировка на мониторе).

Другими словами, когда поток пытается получить доступ к синхронизированному методу, а другой поток уже находится внутри, состояние изменяется на BLOCKED:

@Test void shouldReturnBlockedState() throws InterruptedException { // Given final Thread synchronizedThread = new Thread(this::synchronizedMethod); final Thread blockedThread = new Thread(this::synchronizedMethod); // When synchronizedThread.start(); blockedThread.start(); // Then Thread.sleep(10); assertThat(blockedThread.getState()).isEqualTo(Thread.State.BLOCKED); }
Code language: PHP (php)

WAITING

Переход потока в состояние WAITING происходит, когда поток ожидает другие потоки.

Это не ожидание, как в критической секции, а ожидание, вызываемое, например, методом wait() или join():

@Test void shouldReturnWaitingState() throws InterruptedException { // Given final Thread waitingThread = new Thread(this::synchronizedMethod); final Thread wrapperThread = new Thread(() -> { waitingThread.start(); try { Thread.currentThread().join(); } catch(InterruptedException e) { e.printStackTrace(); } }); // When wrapperThread.start(); // Then Thread.sleep(10); assertThat(wrapperThread.getState()).isEqualTo(Thread.State.WAITING); }
Code language: PHP (php)

TIMED_WAITING

С каждым из нас случалось усыпить поток. Затем он переходит в состояние TIMED_WAITING.

Это состояние также появляется, когда мы используем методы для ожидания других потоков (например, wait() или join()), которые принимают значения времени в качестве параметров:

@Test void shouldReturnTimedWaitingState() throws InterruptedException { // Given final Thread timedWaitingThread = new Thread(() -> { try { Thread.sleep(1_000); } catch (InterruptedException e) { e.printStackTrace(); } }); // When timedWaitingThread.start(); // Then Thread.sleep(10); assertThat(timedWaitingThread.getState()).isEqualTo(Thread.State.TIMED_WAITING); }
Code language: JavaScript (javascript)

TERMINATED

Когда поток завершает свою работу (то есть, когда завершается метод run()), он переходит в состояние TERMINATED:

@Test void shouldReturnTerminatedState() throws InterruptedException { // Given final Thread terminatedThread = new Thread(()->{}); // When terminatedThread.start(); terminatedThread.join(); // Then assertThat(terminatedThread.getState()).isEqualTo(Thread.State.TERMINATED); }
Code language: JavaScript (javascript)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *