多线程编程中如何确保子线程执行完毕后主线程再执行-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);
	    }
  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦里藍天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值