Класс Condition
Класс Condition представляет собой механизм синхронизации,
который позволяет одному потоку приостановить своё выполнение
(ждать), а другому потоку - подать сигнал о том, что условие
наступило. Объект Condition создаётся не напрямую,
а через метод newCondition интерфейса Lock
(например, у класса ReentrantLock).
Основные методы класса: await - приостанавливает
текущий поток до получения сигнала, signal - будит
один ожидающий поток, signalAll - будит все
ожидающие потоки. Метод await освобождает
связанную блокировку на время ожидания и автоматически
захватывает её снова перед возвратом. В первый параметр
метода await можно передать время ожидания,
во второй - единицу измерения времени.
Синтаксис
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
condition.await();
condition.await(time, unit);
condition.signal();
condition.signalAll();
Пример
Давайте создадим поток, который ждёт сигнала, и поток, который этот сигнал подаёт:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Main
{
public static void main(String[] args) throws InterruptedException
{
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Thread waiter = new Thread(() -> {
lock.lock();
try {
System.out.println("waiter is waiting");
condition.await();
System.out.println("waiter is awake");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
});
waiter.start();
Thread.sleep(500);
lock.lock();
try {
System.out.println("sending signal");
condition.signal();
} finally {
lock.unlock();
}
}
}
Результат выполнения кода:
"waiter is waiting"
"sending signal"
"waiter is awake"
Пример
Давайте используем signalAll, чтобы разбудить
сразу несколько ожидающих потоков:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Main
{
public static void main(String[] args) throws InterruptedException
{
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
for (int i = 1; i <= 3; i++) {
final int id = i;
new Thread(() -> {
lock.lock();
try {
System.out.println("thread " + id + " is waiting");
condition.await();
System.out.println("thread " + id + " is awake");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}).start();
}
Thread.sleep(500);
lock.lock();
try {
System.out.println("sending signalAll");
condition.signalAll();
} finally {
lock.unlock();
}
}
}
Результат выполнения кода:
"thread 1 is waiting"
"thread 2 is waiting"
"thread 3 is waiting"
"sending signalAll"
"thread 1 is awake"
"thread 2 is awake"
"thread 3 is awake"
Смотрите также
-
метод
await,
который приостанавливает поток до сигнала -
метод
signal,
который будит один ожидающий поток -
метод
signalAll,
который будит все ожидающие потоки -
класс
ReentrantLock,
который создаёт объект Condition