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

线程的奥秘:如果你碰到一个题目需要执行完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();



    }
}

结果:

线程之-倒计时器CountDownLatch+循环栅栏_第1张图片

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

线程之-倒计时器CountDownLatch+循环栅栏_第2张图片


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

假设一个长官命令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

打印结果如下: 

开始集合队伍
士兵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

 

你可能感兴趣的:(JAVA)