目录
1. CountDownLatch含义
CountDownLatch: 从字面以上的意思是“门闩到计数”。也就是让一个线程或者多个线程等待其他线程结束后再继续自己的操作,类似加强版join().
通过一个简单的应用场景来说明一下上面一句话的意思:
比如火箭发射,为了保证火箭发射万无一失,必须在火箭发射之间进行各项的检查初始化工作。假设在火箭发射之间进行100项的初始化检查工作(此时的100就是我们设置的"门闩"),只有这100项工作结束后,才能进行接下来的“点火发射”操作。
因此,就可以通过CountDownLatch设置一个“倒计数器”,记录初始化工作的完成情况。所以,在“点火发射”操作必须等待所有的初始化工作完成之后才能进行。
2. CountDownLatch主要方法:
1. 通过创建CountdownLatch的实例,初始化一个计数器 CountDownLatch latch = new CountDownLatch(100);
2. 每次执行完一个初始化的线程后,计数器-1 latch.countDown()
3. 后续工作需要等待所有初始化工作完成后才能进行(等待)。 latch.await();
3. 代码示例:
要求:服务线程必须在6个初始化线程完成之后才能去执行
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 测试CountDownLatch工具类,
*
* 要求:当6个初始化线程完成后再去执行服务线程
*
* Created by songyangguang on 2018/7/21.
*/
public class CountDownLatchTest {
//定义倒计时器容量是6
static CountDownLatch countDownLatch = new CountDownLatch(6);
//创建一个初始化的内部类
private static class initClass extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "InitClass is Running");
countDownLatch.countDown();//程序计数器-1
}
}
//创建一个处理服务的内部类
private static class ServiceClass extends Thread{
@Override
public void run() {
try {
//此时,服务线程会等待初始化线程结束(计数器 = 0)时才会执行
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" ServiceClass is Running!");
}
}
public static void main(String[] args) {
//创建有8个线程的线程池
ExecutorService threadPool = Executors.newFixedThreadPool(8);
//此时服务线程不会立刻执行,而是等待所有初始化的线程结束后才能运行(等待6个初始化线程结束)
for (int j = 0; j < 2; j++) {
threadPool.submit(new ServiceClass());
}
//初始化线程运行
for (int i = 0; i < 6; i++) {
threadPool.submit(new initClass());
}
System.out.println("This is the main thread!");
}
}
运行结果: