线程之-倒计时器CountDownLatch+循环栅栏

本文介绍了Java并发编程中线程控制的两种工具:CountDownLatch和CyclicBarrier。通过实例展示了如何使用CountDownLatch实现火箭发射前的多线程倒计时检查,以及如何利用CyclicBarrier实现线程的同步,确保所有线程完成任务后才进行下一步操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程的奥秘:如果你碰到一个题目需要执行完10个或者n个才能轮到下一个线程执行的案例你需要采用怎样的方法?这时候简单实用倒计时器CountDownLatch

现在做一个火箭发射前检查完10道工序再发射的多线程控制原型:

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLactateDemo implements  Runnable {
    static  CountDownLactateDemo demo=new CountDownLactateDemo();
    static  int i=0;
    static  final CountDownLatch countDownLatch=new CountDownLatch(10);//计数数量为10,10个线程执行完才轮到下一个来执行。
    @Override
    public void run() {
        try {
            Thread.sleep(new Random().nextInt(10)*1000);
            i++;
            System.out.println( i+" "+"check process");
            countDownLatch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }
    public static void  main(String[] args) throws InterruptedException {
        ExecutorService exec= Executors.newFixedThreadPool(10);
        for (int j=0;j<10;j++){
            exec.submit(demo);
        }
        countDownLatch.await();//要求主线程等待10个线程执行完毕
        System.out.println( "launch");//执行完10个后火箭才发射
        exec.shutdown();



    }
}

结果:

这时候我们要求主线程只等待9个检查工序就发射火箭,发送火箭后执行第10个线程,通知发射成功类似。只需要修改等待线程为9个就可以了,输出结果为:


循环栅栏可以视作为反复使用的倒数计数器

假设一个长官命令10个士兵集合,集合完毕长官发布集合完毕,然后10个士兵完成任务后长官发布任务完成完毕。都必须等这线程任务完成才可以发布,代码如下:

import java.util.Random;
import java.util.concurrent.*;

public class CyclicBarrierDemo {
    public static class Sodier implements Runnable{
        private CyclicBarrier cyclic;
        private  String soldier;
        Sodier(CyclicBarrier cyclicBarrier,String soldierName){
            this.cyclic=cyclicBarrier;
            this.soldier=soldierName;

        }

        @Override
        public void run() {
            //等待所有士兵到达
            try {
                cyclic.await();
                //全部达到后执行下一步
                doWork();
                cyclic.await();
                //等待所有线程doWork任务完成
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }


        }
        void doWork(){
            System.out.println( soldier+" "+"任务完成!");
        }
    }
    public static class BarrierRun implements  Runnable{
        boolean flag;
        int N=10;
        BarrierRun(boolean flag,int N){
            this.flag=flag;
            this.N=N;
        }

        @Override
        public void run() {
            if (flag){
                System.out.println("长官:"+N+ "个士兵集合完毕");
                flag=false;
            }else{
                System.out.println( "长官"+N+"个士兵任务完成");

            }
        }
    }



    public static void  main(String[] args) throws InterruptedException {
       boolean flag=true;
       final int N=10;
       Thread[] thread=new Thread[N];
       CyclicBarrier cyclicBarrier=new CyclicBarrier(N,new BarrierRun(true,N));
        //加入10个等待线程,完成计数器指标后执行第二参数new BarrierRun(true,N),只要调用await后计数完毕都会调用该线程
        System.out.println( "开始集合队伍");
        for (int i=0;i<N;++i){
            System.out.println( "士兵"+i+"报道!");
            thread[i]=new Thread(new Sodier(cyclicBarrier,"士兵"+i));
            thread[i].start();;
        }

    }
}

打印结果如下: 

开始集合队伍
士兵0报道!
士兵1报道!
士兵2报道!
士兵3报道!
士兵4报道!
士兵5报道!
士兵6报道!
士兵7报道!
士兵8报道!
士兵9报道!
长官:10个士兵集合完毕
士兵8 任务完成!
士兵1 任务完成!
士兵3 任务完成!
士兵5 任务完成!
士兵7 任务完成!
士兵9 任务完成!
士兵2 任务完成!
士兵0 任务完成!
士兵4 任务完成!
士兵6 任务完成!
长官10个士兵任务完成

Process finished with exit code 0

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值