РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
1026 of 1163 menu

Метод signal

Метод signal класса Condition пробуждает один поток, который в данный момент ожидает на этом условии. Если таких потоков несколько, выбирается один из них. Метод не принимает параметров и ничего не возвращает. Перед вызовом метода поток должен захватить блокировку Lock, связанную с данным условием, иначе будет выброшено исключение IllegalMonitorStateException.

Метод signal является аналогом метода notify класса Object, но работает в связке с Condition и Lock вместо встроенной синхронизации. Пробуждённый поток не начнёт выполняться сразу - ему ещё нужно дождаться освобождения блокировки.

Синтаксис

condition.signal()

Пример

Давайте создадим условие и разбудим ожидающий поток с помощью signal:

import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Main { public static void main(String[] args) throws InterruptedException { ReentrantLock lock = new ReentrantLock(); Condition condition = lock.newCondition(); Thread waiter = new Thread(() -> { lock.lock(); try { System.out.println("waiting"); condition.await(); System.out.println("awakened"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { lock.unlock(); } }); waiter.start(); Thread.sleep(100); lock.lock(); try { condition.signal(); } finally { lock.unlock(); } waiter.join(); } }

Результат выполнения кода:

"waiting" "awakened"

Пример

Давайте посмотрим, что произойдёт, если вызвать signal без захвата блокировки:

import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Main { public static void main(String[] args) { ReentrantLock lock = new ReentrantLock(); Condition condition = lock.newCondition(); try { condition.signal(); } catch (IllegalMonitorStateException e) { System.out.println("exception caught"); } } }

Результат выполнения кода:

"exception caught"

Пример

Давайте разбудим один поток из нескольких ожидающих с помощью signal:

import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class Main { public static void main(String[] args) throws InterruptedException { ReentrantLock lock = new ReentrantLock(); Condition condition = lock.newCondition(); Runnable task = () -> { lock.lock(); try { condition.await(); System.out.println(Thread.currentThread().getName()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { lock.unlock(); } }; Thread t1 = new Thread(task, "t1"); Thread t2 = new Thread(task, "t2"); t1.start(); t2.start(); Thread.sleep(100); lock.lock(); try { condition.signal(); } finally { lock.unlock(); } t1.join(); lock.lock(); try { condition.signal(); } finally { lock.unlock(); } t2.join(); } }

Результат выполнения кода:

"t1" "t2"

Смотрите также

  • метод await,
    который заставляет поток ожидать на условии
  • метод signalAll,
    который пробуждает все ожидающие потоки
  • класс Condition,
    который представляет условие ожидания
  • класс ReentrantLock,
    который создаёт блокировку и условие
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить