CountDownLatch被用来同步一个或多个任务,强制它们等待由其它任务执行的一组操作完成。
构造方法CountDownLatch(int count)
构造一个用给定计数初始化的 CountDownLatch
。
任何在这个对象上调用await()的方法将会被阻塞,直至这个技术值为0。其他任务在结束其工作时,可以在该对象上调用countDown()来减小这个计数值。CountDownLatch被设计为只触发一次,计数值不能被重置。如果需要重置计数值的版本,则可以调用CyclicBarrier。调用countDown()的任务在产生这个调用时并没有被阻塞,只有对await()的调用会被阻塞,直至计数值到达0。CountDownLatch的典型用法是将一个程序分为n个互相独立的可解决任务,并创建值为n的CountDownLatch。当每个任务完成时,都会在锁存器上调用countDown()。等待问题被解决的任务在这个锁存器上调用await(),将它们自己拦住,直至锁存器计数结束。
示例:
package thread;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class CountDownLatchDemo {
static final int SIZE = 100;
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
CountDownLatch latch = new CountDownLatch(100);
for(int i=0;i<10;i++)
exec.execute(new WaitingTask(latch));
for(int i=0;i<SIZE;i++)
exec.execute(new TaskPortion(latch));
System.out.println("Launched all tasks");
exec.shutdown();
}
}
class WaitingTask implements Runnable{
private static int counter = 0;
private final int id = counter++;
private final CountDownLatch latch;
WaitingTask(CountDownLatch latch){
this.latch = latch;
}
@Override
public void run() {
try {//该任务等待
latch.await();
System.out.println("Latch barrier passed for "+latch);
} catch (InterruptedException e) {
System.out.println(this+" interrupted");
}
}
public String toString(){
return String.format("WaitingTask %1$-3d", id);
}
}
class TaskPortion implements Runnable{
private static int counter = 0;
private final int id = counter++;
private static Random rand = new Random(47);
private final CountDownLatch latch;
public TaskPortion(CountDownLatch latch){
this.latch = latch;
}
@Override
public void run() {
try{
doWork();
//每次完成一个任务,调用countDown使计数值减一
latch.countDown();
}catch(Exception e){
}
}
public void doWork() throws Exception{
TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000));
System.out.println(this+" completed");
}
public String toString(){
return String.format("%1$-3d", id);
}
}
输出:
Launched all tasks
37 completed
45 completed
99 completed
95 completed
94 completed
11 completed
23 completed
77 completed
7 completed
9 completed
75 completed
10 completed
79 completed
39 completed
25 completed
36 completed
96 completed
63 completed
30 completed
40 completed
55 completed
90 completed
28 completed
88 completed
6 completed
50 completed
8 completed
12 completed
0 completed
27 completed
13 completed
98 completed
72 completed
71 completed
2 completed
43 completed
35 completed
15 completed
91 completed
18 completed
5 completed
33 completed
97 completed
21 completed
69 completed
34 completed
4 completed
68 completed
38 completed
48 completed
87 completed
70 completed
84 completed
86 completed
66 completed
54 completed
42 completed
29 completed
46 completed
74 completed
57 completed
1 completed
20 completed
65 completed
80 completed
16 completed
60 completed
89 completed
14 completed
51 completed
53 completed
62 completed
58 completed
76 completed
92 completed
22 completed
19 completed
56 completed
85 completed
61 completed
31 completed
26 completed
24 completed
59 completed
67 completed
47 completed
41 completed
32 completed
3 completed
52 completed
93 completed
81 completed
78 completed
73 completed
44 completed
49 completed
17 completed
82 completed
64 completed
83 completed
Latch barrier passed for java.util.concurrent.CountDownLatch@189e7143[Count = 0]
Latch barrier passed for java.util.concurrent.CountDownLatch@189e7143[Count = 0]
Latch barrier passed for java.util.concurrent.CountDownLatch@189e7143[Count = 0]
Latch barrier passed for java.util.concurrent.CountDownLatch@189e7143[Count = 0]
Latch barrier passed for java.util.concurrent.CountDownLatch@189e7143[Count = 0]
Latch barrier passed for java.util.concurrent.CountDownLatch@189e7143[Count = 0]
Latch barrier passed for java.util.concurrent.CountDownLatch@189e7143[Count = 0]
Latch barrier passed for java.util.concurrent.CountDownLatch@189e7143[Count = 0]
Latch barrier passed for java.util.concurrent.CountDownLatch@189e7143[Count = 0]
Latch barrier passed for java.util.concurrent.CountDownLatch@189e7143[Count = 0]
从中可以看出WaitingTask最后执行,count=0;