定义 【java|多线程编程中如何确保子线程执行完毕后主线程再执行-CountDownLatch】ountDownLatch是在java1.5被引入,存在于java.util.cucurrent包下,跟它一起被引入的工具类还有CyclicBarrier、Semaphore、concurrentHashMap和BlockingQueue。
countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行,它是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。
线性执行的案例 在多线程开发中,主线程数据通过子线程处理后返回的结果往往并不是我们想要的。如下面一个例子,我们的期望结果是300000,但是在主线程输出后并不是我们想要的:
public static AtomicInteger num = new AtomicInteger(0);
public static void main(String []args) throws InterruptedException {
//开启30个线程进行累加操作
for(int i=0;
i<30;
i++){
new Thread(){
public void run(){
for(int j=0;
j<10000;
j++){
num.incrementAndGet();
//原子性的num++,通过循环CAS方式
}
}
}.start();
}
System.out.println(num);
}
上面的这个例子中,num操作是原子的,线程安全的,输出的结果并不是我们想要的,是应为主线程输出时子线程还有没有结束。以下面的的代码来验证我们的想法:
public static AtomicInteger num = new AtomicInteger(0);
public static void main(String []args) throws InterruptedException {
//开启30个线程进行累加操作
for(int i=0;
i<30;
i++){
new Thread(){
public void run(){
for(int j=0;
j<10000;
j++){
num.incrementAndGet();
//原子性的num++,通过循环CAS方式
}
}
}.start();
}
//等待计算线程执行完
TimeUnit.MILLISECONDS.sleep(1000);
System.out.println(num);
}
此时我们输出的结果就是300000了;这是我们在开发中已经预估到子线程的算法不会超过1000毫秒,如果在开发中不能确保估算的时间准确,或者估算的时间较长造成资源浪费怎么办?使用CountDownLatch即可解决这个问题。
文章图片
上图来自JDK8的API接口文档,主要有1个构造方法5个方法。
如何改造上面的代码?
public static AtomicInteger num = new AtomicInteger(0);
//使用CountDownLatch来等待计算线程执行完
static CountDownLatch countDownLatch = new CountDownLatch(30);
public static void main(String []args) throws InterruptedException {
//开启30个线程进行累加操作
for(int i=0;
i<30;
i++){
new Thread(){
public void run(){
for(int j=0;
j<10000;
j++){
num.incrementAndGet();
//原子性的num++,通过循环CAS方式
}
countDownLatch.countDown();
}
}.start();
System.out.println("剩余数量"+countDownLatch.getCount());
}
//等待计算线程执行完
countDownLatch.await();
System.out.println(num);
}
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)