zl程序教程

您现在的位置是:首页 >  后端

当前栏目

java多线程:循环屏障

2023-09-27 14:23:43 时间

本文是视频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玩家选择英雄