public class CountDownLatch
extends Object
java.lang.Object | |
↳ | java.util.concurrent.CountDownLatch |
同步协助,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。
A CountDownLatch
用给定的计数进行初始化。 await
方法会阻塞,直到当前计数由于调用countDown()
方法而达到零,此后所有等待的线程被释放,并且任何后续调用await
立即返回。 这是一次性现象 - 计数无法重置。 如果您需要重置计数的版本,请考虑使用CyclicBarrier
。
A CountDownLatch
是一款多功能同步工具,可用于多种用途。 一个CountDownLatch
初始化为1的计数用作简单的开/关锁存器或门:调用await
所有线程在门await
等待,直到它被调用countDown()
的线程打开countDown()
。 初始化为N的CountDownLatch
可用于使一个线程等待,直到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来描述每个部分,该部分执行该部分并在锁存器上进行倒计数,并将所有Runnables排队到Executor。 当所有子部分完成时,协调线程将能够通过等待。 (当线程必须以这种方式重复倒数时,请使用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()
happen-before操作之前,线程中的操作 await()
在另一个线程中对应的 await()
成功返回 之后执行。
Public constructors |
|
---|---|
CountDownLatch(int count) 构造一个使用给定计数初始化的 |
Public methods |
|
---|---|
void |
await() 导致当前线程等待,直到锁存器计数到零,除非线程为 interrupted 。 |
boolean |
await(long timeout, TimeUnit unit) 导致当前线程等待,直到锁存器计数到零,除非线程为 interrupted ,或经过了指定的等待时间。 |
void |
countDown() 递减锁存器的计数,如果计数达到零,释放所有等待的线程。 |
long |
getCount() 返回当前计数。 |
String |
toString() 返回标识此闩锁的字符串以及其状态。 |
Inherited methods |
|
---|---|
From class java.lang.Object
|
CountDownLatch (int count)
构造一个用给定计数初始化的 CountDownLatch
。
Parameters | |
---|---|
count |
int : the number of times countDown() must be invoked before threads can pass through await() |
Throws | |
---|---|
IllegalArgumentException |
if count is negative |
void await ()
导致当前线程一直等到锁存器计数到零,除非线程为 interrupted 。
如果当前计数为零,则此方法立即返回。
如果当前计数大于零,则当前线程因为线程调度目的而被禁用,并且处于休眠状态,直到发生以下两种情况之一:
countDown()
method; or 如果当前线程:
InterruptedException
is thrown and the current thread's interrupted status is cleared.
Throws | |
---|---|
InterruptedException |
if the current thread is interrupted while waiting |
boolean await (long timeout, TimeUnit unit)
导致当前线程等待,直到锁存器计数到零,除非线程为 interrupted ,或经过了指定的等待时间。
如果当前计数为零,则此方法立即返回值 true
。
如果当前计数大于零,则当前线程因为线程调度目的而被禁用,并且处于休眠状态,直到发生以下三件事之一:
countDown()
method; or 如果计数达到零,则该方法返回值 true
。
如果当前线程:
InterruptedException
is thrown and the current thread's interrupted status is cleared.
如果经过了指定的等待时间,则返回值false
。 如果时间小于或等于零,该方法将不会等待。
Parameters | |
---|---|
timeout |
long : the maximum time to wait |
unit |
TimeUnit : the time unit of the timeout argument |
Returns | |
---|---|
boolean |
true if the count reached zero and false if the waiting time elapsed before the count reached zero |
Throws | |
---|---|
InterruptedException |
if the current thread is interrupted while waiting |
void countDown ()
递减锁存器的计数,如果计数达到零,释放所有等待的线程。
如果当前计数大于零,那么它是递减的。 如果新计数为零,则所有等待的线程都将重新启用以进行线程调度。
如果当前计数等于零,则不会发生任何事情。
long getCount ()
返回当前计数。
此方法通常用于调试和测试目的。
Returns | |
---|---|
long |
the current count |
String toString ()
返回标识此闩锁的字符串以及其状态。 括号中的状态包括字符串"Count ="
后跟当前计数。
Returns | |
---|---|
String |
a string identifying this latch, as well as its state |