一、CountDownLatch的概念及应用场景。
CountDownLatch是AQS的一个实现类,主要提供了对多个线程进行协调、控制的作用,如作为开关,控制多个线程同时开始工作,或者在主线程等待所有子线程的执行完成。CountDownLatch相当于一个倒计时的实现,每个线程都可以进行递减,待递减到0时,说明时间到了,或者全部线程的功能做都完成了,此时主线程可以阻塞返回。
二、示例1--等待所有子线程执行完成
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 所有子任务完成以后,主线程汇总
*/
public class CountDownLatchDemo {
public static void main(String[] args) {
int n = 10;
CountDownLatch doneSign = new CountDownLatch(n);
ExecutorService service = Executors.newCachedThreadPool();
for (int i=0;i<n;i++ ) {
service.execute(new WorkerRunnable(i,doneSign));
}
try {
doneSign.await();
System.out.println("所有任务执行完成!");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
service.shutdown();
}
}
static class WorkerRunnable implements Runnable{
private CountDownLatch downLatch;
private int i;
public WorkerRunnable(int i,CountDownLatch downLatch){
this.downLatch = downLatch;
this.i = i;
}
@Override
public void run() {
doWork(this.i);
//倒计时同步器递减
downLatch.countDown();
}
public void doWork(int i){
System.out.println("第"+i+"个任务已完成");
}
}
}
三、示例2-作为开关,让所有子线程同时开始执行
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 主线程开启开关后,子任务开始工作
*/
public class CountDownLatchDemo1 {
public static void main(String[] args) {
//因为是开关,所以数量设置为1,递减一次即打开开关
CountDownLatch mainThread = new CountDownLatch(1);
int n =10;
CountDownLatch childThread = new CountDownLatch(n);
ExecutorService service = Executors.newCachedThreadPool();
for (int i=0;i<n;i++ ) {
service.execute(new WorkerRunnable(i,mainThread,childThread));
}
//主线程打开开关,子线程开始执行。
System.out.println("主线程打开开关,子线程开始执行。");
mainThread.countDown();
//子线程执行完毕,进行汇总。
try {
childThread.await();
System.out.println("所有任务执行完成!");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
service.shutdown();
}
}
static class WorkerRunnable implements Runnable{
private CountDownLatch mainThread;
private CountDownLatch childThread;
private int i;
public WorkerRunnable(int i,CountDownLatch mainThread,CountDownLatch childThread){
this.childThread = childThread;
this.mainThread = mainThread;
this.i = i;
}
@Override
public void run() {
try {
//阻塞(开关关闭,等待打开,开关在主线程里会打开)
mainThread.await();
doWork(this.i);
//子线程的倒计时递减,由主线程阻塞汇总。
childThread.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void doWork(int i){
System.out.println("第"+i+"个任务已完成");
}
}
}