• Java并发编程-关卡


    CyclicBarrier 直译过来叫循环栅栏,它主要的方法就是一个:await()。await() 方法没被调用一次,计数便会减少1,并阻塞住当前线程。当计数减至0时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。在这之后,如果再次调用 await() 方法,计数就又会变成 N-1,新一轮重新开始,这便是 Cyclic 的含义所在。

    CyclicBarrier 的使用并不难,但需要主要它所相关的异常。除了常见的异常,CyclicBarrier.await() 方法会抛出一个独有的 BrokenBarrierException。这个异常发生在当某个线程在等待本 CyclicBarrier 时被中断或超时或被重置时,其它同样在这个 CyclicBarrier 上等待的线程便会受到 BrokenBarrierException。意思就是说,同志们,别等了,有个小伙伴已经挂了,咱们如果继续等有可能会一直等下去,所有各回各家吧。

    CyclicBarrier.await() 方法带有返回值,用来表示当前线程是第几个到达这个 Barrier 的线程。

    和 CountDownLatch 一样,CyclicBarrier 同样可以可以在构造函数中设定总计数值。与 CountDownLatch 不同的是,CyclicBarrier 的构造函数还可以接受一个 Runnable,会在 CyclicBarrier 被释放时执行。

    public class CyclicBarrierTest {
    
            public static void main(String[] args) throws IOException, InterruptedException {
                //如果将参数改为4,但是下面只加入了3个选手,这永远等待下去
                //Waits until all parties have invoked await on this barrier.
                CyclicBarrier barrier = new CyclicBarrier(3);
    
                ExecutorService executor = Executors.newFixedThreadPool(3);
                executor.submit(new Thread(new Runner(barrier, "1号选手")));
                executor.submit(new Thread(new Runner(barrier, "2号选手")));
                executor.submit(new Thread(new Runner(barrier, "3号选手")));
    
                executor.shutdown();
            }
        }
    
        class Runner implements Runnable {
            // 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)
            private CyclicBarrier barrier;
    
            private String name;
    
            public Runner(CyclicBarrier barrier, String name) {
                super();
                this.barrier = barrier;
                this.name = name;
            }
    
            @Override
            public void run() {
                try {
                    Thread.sleep(1000 * (new Random()).nextInt(8));
                    System.out.println(name + " 准备好了...");
                    // barrier的await方法,在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println(name + " 起跑!");
            }
        }
    

    CountDownLatch 适用于一组线程和另一个主线程之间的工作协作。一个主线程等待一组工作线程的任务完毕才继续它的执行是使用 CountDownLatch 的主要场景;CyclicBarrier 用于一组或几组线程,比如一组线程需要在一个时间点上达成一致,例如同时开始一个工作。另外,CyclicBarrier 的循环特性和构造函数所接受的 Runnable 参数也是 CountDownLatch 所不具备的。

  • 相关阅读:
    Emacs教程
    华为上机测试 2015
    奇偶排序
    C语言中的EOF和回车不一样
    jquery 使用方法
    1116
    1115
    1109
    Oracle14~23
    get与post的区别
  • 原文地址:https://www.cnblogs.com/suxuan/p/4948752.html
Copyright © 2020-2023  润新知