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玩家选择英雄
    
  • 相关阅读:
    3dsmaxunity3d
    libav android移植交叉编译
    libav 由显卡中读取数据制作视频
    超详细mysql left join,right join,inner join用法分析
    VC常见入门问题总结
    c#皮肤美化
    论坛
    vc中文件的读写操作
    MySQL的mysqldump工具的基本用法
    perl产生随机数
  • 原文地址:https://www.cnblogs.com/jiading/p/12368912.html
Copyright © 2011-2022 走看看