zoukankan      html  css  js  c++  java
  • java多线程:循环屏障

    本文是视频https://www.bilibili.com/video/av81181427 的笔记

    循环屏障

    前一篇中,我们讲了多线程中的计数器。这里我们来讲循环屏障。
    其实循环屏障的功能和计数器很像,它可以看成是计数器的countdown和await方法的组合。但是这就是区别所在:如果你把countDownLatch的await设置了主线程,那么就可以实现主线程等子线程执行完了之后再执行的效果;而循环屏障是统一了子线程之间的执行,也就是说如果要阻塞主线程的话,需要将循环屏障放在子线程任务完成之后、放在主线程创建完子线程之后

    public static void main(String[] args) throws InterruptedException {
            CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
            for (int i = 0; i < 10; i++) {
                new Thread(() -> {
                    try {
                        Thread.sleep(new Double(Math.random() * 3000).longValue());
                        System.out.println(Thread.currentThread().getName() + "玩家准备就绪");
                        cyclicBarrier.await();
                        System.out.println(Thread.currentThread().getName() + "玩家选择英雄");
                    } catch (InterruptedException | BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }).start();
            }
        }
    

    它的输出为:

    Thread-2玩家准备就绪
    Thread-4玩家准备就绪
    Thread-3玩家准备就绪
    Thread-1玩家准备就绪
    Thread-0玩家准备就绪
    Thread-0玩家选择英雄
    Thread-2玩家选择英雄
    Thread-3玩家选择英雄
    Thread-4玩家选择英雄
    Thread-1玩家选择英雄
    

    可以看到,当循环屏障内部的数减到0之前,所有的线程都阻塞在cyclicBarrier中
    它的效果和下面使用countdown的组合方法一样:

    CountDownLatch countDownLatch=new CountDownLatch(5);
            for(int i=0;i<10;i++){
                new Thread(()->{
                    try{
                        Thread.sleep(new Double(Math.random()*3000).longValue());
                        System.out.println(Thread.currentThread().getName()+"玩家准备就绪");
                        countDownLatch.countDown();//计数点
                        countDownLatch.await();
                        System.out.println(Thread.currentThread().getName()+"玩家选择英雄");
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }).start();
            }
    

    至于它为什么叫“循环”屏障,这是因为它内部的数字在减到0之后是可以恢复到原来的,例如,如果我们参数依然保持是5,但是创建10个线程时:

    Thread-4玩家准备就绪
    Thread-5玩家准备就绪
    Thread-2玩家准备就绪
    Thread-1玩家准备就绪
    Thread-3玩家准备就绪
    Thread-3玩家选择英雄
    Thread-4玩家选择英雄
    Thread-5玩家选择英雄
    Thread-2玩家选择英雄
    Thread-1玩家选择英雄
    Thread-0玩家准备就绪
    Thread-6玩家准备就绪
    Thread-7玩家准备就绪
    Thread-8玩家准备就绪
    Thread-9玩家准备就绪
    Thread-9玩家选择英雄
    Thread-0玩家选择英雄
    Thread-6玩家选择英雄
    Thread-7玩家选择英雄
    Thread-8玩家选择英雄
    
  • 相关阅读:
    [TJOI2019]大中锋的游乐场——最短路+DP
    [TJOI2019]甲苯先生的滚榜——非旋转treap
    [TJOI2019]甲苯先生的字符串——矩阵乘法+递推
    [TJOI2019]唱、跳、rap和篮球——NTT+生成函数+容斥
    [ZJOI2020]字符串
    Ubuntu 20.04 工作区小记
    2020省选犯傻记
    寒假到省选的一些笔记
    AtCoder tokiomarine2020 题解
    [CF1336E]Chiori and Doll Picking
  • 原文地址:https://www.cnblogs.com/jiading/p/12368912.html
Copyright © 2011-2022 走看看