zoukankan      html  css  js  c++  java
  • CyclicBarrier 使用详解(转)

    转自:https://www.jianshu.com/p/333fd8faa56e

    1. CyclicBarrier 是什么?

    从字面上的意思可以知道,这个类的中文意思是“循环栅栏”。大概的意思就是一个可循环利用的屏障。

    它的作用就是会让所有线程都等待完成后才会继续下一步行动。

    举个例子,就像生活中我们会约朋友们到某个餐厅一起吃饭,有些朋友可能会早到,有些朋友可能会晚到,但是这个餐厅规定必须等到所有人到齐之后才会让我们进去。这里的朋友们就是各个线程,餐厅就是 CyclicBarrier。

    2. 怎么使用 CyclicBarrier

    2.1 构造方法

    public CyclicBarrier(int parties)
    public CyclicBarrier(int parties, Runnable barrierAction)

    解析:

    • parties 是参与线程的个数
    • 第二个构造方法有一个 Runnable 参数,这个参数的意思是最后一个到达线程要做的任务

    2.2 重要方法

    public int await() throws InterruptedException, BrokenBarrierException
    public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException

    解析:

    • 线程调用 await() 表示自己已经到达栅栏
    • BrokenBarrierException 表示栅栏已经被破坏,破坏的原因可能是其中一个线程 await() 时被中断或者超时

    2.3 基本使用

    2.3.1 需求

    一个线程组的线程需要等待所有线程完成任务后再继续执行下一次任务

    2.3.2 代码实现

    public class CyclicBarrierDemo {
    
        static class TaskThread extends Thread {
            
            CyclicBarrier barrier;
            
            public TaskThread(CyclicBarrier barrier) {
                this.barrier = barrier;
            }
            
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    System.out.println(getName() + " 到达栅栏 A");
                    barrier.await();
                    System.out.println(getName() + " 冲破栅栏 A");
                    
                    Thread.sleep(2000);
                    System.out.println(getName() + " 到达栅栏 B");
                    barrier.await();
                    System.out.println(getName() + " 冲破栅栏 B");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        
        public static void main(String[] args) {
            int threadNum = 5;
            CyclicBarrier barrier = new CyclicBarrier(threadNum, new Runnable() {
                
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " 完成最后任务");
                }
            });
            
            for(int i = 0; i < threadNum; i++) {
                new TaskThread(barrier).start();
            }
        }
        
    }

    打印结果:

    Thread-1 到达栅栏 A
    Thread-3 到达栅栏 A
    Thread-0 到达栅栏 A
    Thread-4 到达栅栏 A
    Thread-2 到达栅栏 A
    Thread-2 完成最后任务
    Thread-2 冲破栅栏 A
    Thread-1 冲破栅栏 A
    Thread-3 冲破栅栏 A
    Thread-4 冲破栅栏 A
    Thread-0 冲破栅栏 A
    Thread-4 到达栅栏 B
    Thread-0 到达栅栏 B
    Thread-3 到达栅栏 B
    Thread-2 到达栅栏 B
    Thread-1 到达栅栏 B
    Thread-1 完成最后任务
    Thread-1 冲破栅栏 B
    Thread-0 冲破栅栏 B
    Thread-4 冲破栅栏 B
    Thread-2 冲破栅栏 B
    Thread-3 冲破栅栏 B

    从打印结果可以看出,所有线程会等待全部线程到达栅栏之后才会继续执行,并且最后到达的线程会完成 Runnable 的任务。

    3. CyclicBarrier 使用场景

    可以用于多线程计算数据,最后合并计算结果的场景。

    4. CyclicBarrier 与 CountDownLatch 区别

    • CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的
    • CountDownLatch 参与的线程的职责是不一样的,有的在倒计时,有的在等待倒计时结束。CyclicBarrier 参与的线程职责是一样的。


    作者:一团捞面
    链接:https://www.jianshu.com/p/333fd8faa56e
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    js中setTimeout、setInterval、 clearInterval方法简介
    分享一个VS2008漂亮的黑色主题
    最简单的设计模式
    记一次查数据的需求
    Oracle常用存储过程写法
    关于域名解析
    使用PHP打造QQ空间神奇图片
    自制小工具含源码——SPTC上海交通卡余额查询
    自制小工具含源码——博客园图床ImageBed
    不可不知的mysql 常用技巧总结
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/15108975.html
Copyright © 2011-2022 走看看