CountDownLatch的使用
适用场景:
一个任务的执行要等到所有任务都执行完后再做操作。
具体用法
以下面的场景为例:
任务 | 执行条件 |
---|---|
A | 无 |
B | 无 |
C | 无 |
D | A、B、C全部执行完 |
实现步骤:
1.在主线程处新建线程池,用于执行任务。
2.新建CountDownLatch实例latch,指定count值。
3.A、B、C三个任务共用同一个CountDownLatch实例latch,在A、B、C的每个任务执行方法的最后调用CountDownLatch的countDown()方法。
4.在要等待的任务D的执行位置的开始处调用CountDownLatch实例latch的await()方法来等待A、B、C三个任务的执行完成。
说明:
具体使用时,A、B、C、D可为独立于主线程的四个单独的线程,也可以是A、B、C是三个独立线程,而D做为主线程来等待A、B、C的完成。
下边以一个具体的实例来做一个示范。
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
*
* @author difeng
*
*/
public class CountDownLatchDemo {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);
CountDownLatch countDownLatch = new CountDownLatch(3);
Producer worker1 = new Producer("producer1","partA",countDownLatch);
Producer worker2 = new Producer("producer2","partB",countDownLatch);
Producer worker3 = new Producer("producer3","partC",countDownLatch);
executorService.execute(worker1);
executorService.execute(worker2);
executorService.execute(worker3);
executorService.execute(new AssemblyWorker(countDownLatch));
executorService.shutdown();
}
}
/**
* 构件生产者
* @author difeng
*
*/
class Producer implements Runnable{
String name;
CountDownLatch countDownLatch;
String partName;
public Producer(String name,String partName,CountDownLatch countDownLatch){
this.name = name;
this.partName = partName;
this.countDownLatch = countDownLatch;
}
public void run() {
System.out.println("I am " + this.name + ",I am making the " + this.partName);
try {
Thread.sleep(new Random().nextInt(10) * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("I am " + this.name + ",My work is done,I submit the " + this.partName + " to AssemblyWorker");
this.countDownLatch.countDown();
}
}
/**
* 组装者
*
*/
class AssemblyWorker implements Runnable{
CountDownLatch countDownLatch;
public AssemblyWorker(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
public void run() {
try {
System.out.println("I am AssemblyWorker,I am waitting for the workers to submit their component");
this.countDownLatch.await();
System.out.println("all work has done,I am assembled");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
执行结果如下:
I am producer2,I am making the partB
I am producer3,I am making the partC
I am producer1,I am making the partA
I am producer3,My work is done,I submit the partC to AssemblyWorker
I am AssemblyWorker,I am waitting for the workers to submit their component
I am producer1,My work is done,I submit the partA to AssemblyWorker
I am producer2,My work is done,I submit the partB to AssemblyWorker
all work has done,I am assembled