Класс CountDownLatch
public class CountDownLatch extends Object
Объект CountDownLatch инициализируется заданным счётчиком. Методы await блокируют выполнение, пока текущее значение счётчика не станет равным нулю в результате вызовов метода countDown(). После этого все ожидающие потоки освобождаются, а все последующие вызовы await немедленно возвращаются. Это одноразовый механизм — сбросить счётчик нельзя. Если вам нужна версия со сбросом счётчика, рассмотрите возможность использования CyclicBarrier.
Объект CountDownLatch — универсальное средство синхронизации, которое можно использовать для различных целей. Объект CountDownLatch, инициализированный значением счётчика, равным единице, служит простым переключателем или заслонкой: все потоки, вызывающие await, ожидают у заслонки, пока поток, вызвавший countDown(), не откроет её. Объект CountDownLatch, инициализированный значением N, можно использовать, чтобы заставить один поток ожидать, пока N потоков не завершат некоторое действие или пока некоторое действие не будет выполнено N раз.
Полезное свойство объекта CountDownLatch состоит в том, что он не требует, чтобы потоки, вызывающие countDown, ожидали достижения счётчиком нуля, прежде чем продолжить выполнение: он просто не позволяет ни одному потоку пройти дальше вызова await, пока все потоки не смогут продолжить выполнение.
Пример использования: Ниже приведена пара классов, в которых группа рабочих потоков использует два обратных отсчёта:
- Первый — сигнал запуска, который не позволяет рабочим потокам продолжать выполнение, пока управляющий поток не будет готов;
- Второй — сигнал завершения, позволяющий управляющему потоку дождаться завершения всех рабочих потоков.
class Driver { // ...
void main() throws InterruptedException {
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i = 0; i < N; ++i) // create and start threads
new Thread(new Worker(startSignal, doneSignal)).start();
doSomethingElse(); // don't let run yet
startSignal.countDown(); // let all threads proceed
doSomethingElse();
doneSignal.await(); // wait for all to finish
}
}
class Worker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
public void run() {
try {
startSignal.await();
doWork();
doneSignal.countDown();
} catch (InterruptedException ex) {} // return;
}
void doWork() { ... }
} Другой типичный вариант использования — разделить задачу на N частей, описать каждую часть с помощью Runnable, который выполняет соответствующую часть и уменьшает значение счётчика, а затем передать все объекты Runnable исполнителю. Когда все подзадачи будут завершены, координирующий поток сможет продолжить выполнение после вызова await. (Если потокам нужно многократно уменьшать счётчик таким образом, используйте вместо этого CyclicBarrier.)
class Driver2 { // ...
void main() throws InterruptedException {
CountDownLatch doneSignal = new CountDownLatch(N);
Executor e = ...;
for (int i = 0; i < N; ++i) // create and start threads
e.execute(new WorkerRunnable(doneSignal, i));
doneSignal.await(); // wait for all to finish
}
}
class WorkerRunnable implements Runnable {
private final CountDownLatch doneSignal;
private final int i;
WorkerRunnable(CountDownLatch doneSignal, int i) {
this.doneSignal = doneSignal;
this.i = i;
}
public void run() {
doWork();
doneSignal.countDown();
}
void doWork() { ... }
} Эффекты согласованности памяти: пока счётчик не достигнет нуля, действия в потоке, предшествующие вызову countDown(), происходят до действий, следующих за успешным возвратом из соответствующего вызова await() в другом потоке.
- Начиная с:
- 1.5
Краткое описание конструкторов
| Конструктор | Описание |
|---|---|
CountDownLatch |
Создаёт объект CountDownLatch с заданным начальным значением счётчика. |
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
void |
await() |
Заставляет текущий поток ожидать, пока значение счётчика не станет равным нулю, если только поток не будет прерван. |
boolean |
await |
Заставляет текущий поток ожидать, пока значение счётчика не станет равным нулю, если только поток не будет прерван или не истечёт заданное время ожидания. |
void |
countDown() |
Уменьшает значение счётчика, освобождая все ожидающие потоки, если счётчик достигнет нуля. |
long |
getCount() |
Возвращает текущее значение счётчика. |
String |
toString() |
Возвращает строку, идентифицирующую этот объект синхронизации и описывающую его состояние. |
Методы, объявленные в классе Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait | Модификатор и тип | Метод | Описание |
|---|---|---|
protected Object |
clone() |
Создаёт и возвращает копию этого объекта. |
boolean |
equals |
Указывает, равен ли этот объект другому объекту. |
protected void |
finalize() |
Устарело, планируется удаление: этот элемент API может быть удалён в будущей версии. Финализация устарела и может быть удалена в одном из следующих выпусков. |
final Class |
getClass() |
Возвращает класс среды выполнения этого объекта Object. |
int |
hashCode() |
Возвращает хеш-код этого объекта. |
final void |
notify() |
Пробуждает один поток, ожидающий на мониторе этого объекта. |
final void |
notifyAll() |
Пробуждает все потоки, ожидающие на мониторе этого объекта. |
final void |
wait() |
Заставляет текущий поток ожидать пробуждения, обычно в результате уведомления или прерывания. |
final void |
wait |
Заставляет текущий поток ожидать пробуждения, обычно в результате уведомления или прерывания, либо истечения заданного промежутка реального времени. |
final void |
wait |
Заставляет текущий поток ожидать пробуждения, обычно в результате уведомления или прерывания, либо истечения заданного промежутка реального времени. |
Подробное описание конструкторов
CountDownLatch
public CountDownLatch(int count)
CountDownLatch с заданным начальным значением счётчика.- Параметры:
-
count— количество вызововcountDown(), необходимых, прежде чем потоки смогут пройти черезawait() - Исключения:
-
IllegalArgumentException— если значениеcountотрицательное
Подробное описание методов
await
public void await() throws InterruptedException
Если текущее значение счётчика равно нулю, этот метод немедленно возвращает управление.
Если текущее значение счётчика больше нуля, планировщик потоков отключает текущий поток, и тот ожидает, пока не произойдёт одно из двух событий:
- Счётчик достигнет нуля в результате вызовов метода
countDown(); или - Другой поток прервёт текущий поток.
Если текущий поток:
- входит в этот метод с установленным флагом прерывания; или
- будет прерван во время ожидания,
InterruptedException, а флаг прерывания текущего потока будет сброшен.- Исключения:
-
InterruptedException— если текущий поток прерван во время ожидания
await
public boolean await(long timeout, TimeUnit unit) throws InterruptedException
Если текущее значение счётчика равно нулю, этот метод немедленно возвращает значение true.
Если текущее значение счётчика больше нуля, планировщик потоков отключает текущий поток, и тот ожидает, пока не произойдёт одно из трёх событий:
- Счётчик достигнет нуля в результате вызовов метода
countDown(); или - Другой поток прервёт текущий поток; или
- Истечёт заданное время ожидания.
Если счётчик достигнет нуля, метод вернёт значение true.
Если текущий поток:
- входит в этот метод с установленным флагом прерывания; или
- будет прерван во время ожидания,
InterruptedException, а флаг прерывания текущего потока будет сброшен. Если заданное время ожидания истечёт, будет возвращено значение false. Если время меньше или равно нулю, метод не будет ждать.
- Параметры:
-
timeout— максимальное время ожидания -
unit— единица измерения времени аргументаtimeout - Возвращает:
-
true, если счётчик достиг нуля, иfalse, если время ожидания истекло до того, как счётчик достиг нуля - Исключения:
-
InterruptedException— если текущий поток прерван во время ожидания
countDown
public void countDown()
Если текущее значение счётчика больше нуля, оно уменьшается. Если новое значение равно нулю, планировщик потоков снова включает все ожидающие потоки.
Если текущее значение счётчика равно нулю, ничего не происходит.
getCount
public long getCount()
Этот метод обычно используется для отладки и тестирования.
- Возвращает:
- текущее значение счётчика
toString
public String toString()
"Count =", за которой следует текущее значение счётчика.
© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.