CountDownLatch可以保证程序在子线程都执行完毕的情况下再执行主线程
使用方法:对CountDownLatch对象设置初值,每个线程执行完后调用countDown方法,计数器减1,所有线程都执行完毕后,计数器为0,继续执行主线程。代码如下:
import java.util.concurrent.CountDownLatch;
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(4);
new Thread(new Worker(startSignal, doneSignal)).start();
new Thread(new Worker(startSignal, doneSignal)).start();
new Thread(new Worker(startSignal, doneSignal)).start();
new Thread(new Worker(startSignal, doneSignal)).start();
System.out.println("主程序执行...");//由于startSignal是1,上边的4个线程还不能执行
startSignal.countDown(); // startSignal=0,线程可以开始执行了
doneSignal.await(); // 等待子线程执行完,然后继续执行下面的代码
System.out.println("开始执行后续任务...");
}
}
class Worker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
@Override
public void run() {
try {
startSignal.await(); //startSignal的计数到0了吗?到0了,才能执行
doWork();
doneSignal.countDown(); //计数减1
} catch (InterruptedException ex) {
}
}
void doWork() {
System.out.println("子线程执行...");
}
}
ExecutorService用来帮忙管理线程池的,线程任务调用submit提交,执行完关闭
ExecutorService executorService = Executors.newCachedThreadPool();
for(int i = 0; i < threadNum; i++){
executorService.submit(new Worker(startSignal, doneSignal));
}
try {
doneSignal.await(); //主线程就能通过await()方法,恢复执行自己的任务
} catch (InterruptedException e){
e.printStackTrace();
}
doOtherThing()
executorService.shutdown();