Spec-Zone.ru › OpenJDK 8

Класс CountDownLatch

  • java.lang.Object
    • java.util.concurrent.CountDownLatch

public class CountDownLatch
extends Object

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

Объект CountDownLatch инициализируется заданным значением count. Методы await блокируют выполнение, пока текущее значение count не достигнет нуля в результате вызовов метода countDown(). После этого все ожидающие потоки освобождаются, и последующие вызовы await возвращаются немедленно. Это одноразовое явление — значение count не может быть сброшено. Если вам нужна версия, которая сбрасывает значение count, рассмотрите использование CyclicBarrier.

Объект CountDownLatch — это универсальный инструмент синхронизации, который можно использовать для различных целей. Объект CountDownLatch с инициализированным значением count равным единице служит простым замком или воротами включения/выключения: все потоки, вызывающие await, ожидают в воротах, пока они не откроются потоком, вызывающим countDown(). Объект CountDownLatch с инициализированным значением N может использоваться для того, чтобы один поток ожидал завершения N потоков, выполнивших некоторое действие, или же пока данное действие было выполнено N раз.

Полезное свойство объекта CountDownLatch заключается в том, что потоки, вызывающие countDown , не требуют ожидания, пока значение count достигнет нуля для продолжения работы; он просто не позволяет ни одному потоку пройти дальше вызова await, пока все потоки не смогут пройти.

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

  • Первый — это сигнал старта, который не позволяет ни одному работнику продолжить работу, пока драйвер не подготовится к их запуску;
  • Второй — это сигнал завершения, который позволяет драйверу ожидать завершения работы всех работников.
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 в Executor. Когда все подзадачи будут завершены, координирующий поток сможет пройти через 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() {
     try {
       doWork(i);
       doneSignal.countDown();
     } catch (InterruptedException ex) {} // return;
   }

   void doWork() { ... }
 }

Влияние согласованности памяти: до тех пор, пока значение счетчика не достигнет нуля, действия в потоке до вызова countDown() предшествуют действиям после успешного возвращения из соответствующего await() в другом потоке.

Since:
1.5

Конструкторы

Конструктор и описание
CountDownLatch(int count)

Создаёт объект CountDownLatch с заданным значением count.

Методы

Модификатор и тип Метод и описание
void await()

Заставляет текущий поток ожидать, пока счётчик не уменьшится до нуля, если поток не прерывается.

boolean await(long timeout, TimeUnit unit)

Заставляет текущий поток ожидать, пока счётчик не уменьшится до нуля, если поток не прерывается или не истекает заданное время ожидания.

void countDown()

Уменьшает значение счётчика замка, освобождая все ожидающие потоки, если счётчик достигнет нуля.

long getCount()

Возвращает текущее значение счётчика.

String toString()

Возвращает строку, идентифицирующую этот замок, а также его состояние.

Методы, унаследованные от класса java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

Подробное описание конструкторов

CountDownLatch

public CountDownLatch(int count)

Создаёт объект CountDownLatch с заданным значением count.

Параметры:
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 =" и текущее значение счётчика.

Переопределяет:
toString в классе Object
Возвращает:
строку, идентифицирующую этот замок, а также его состояние

© 1993, 2020, 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.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API