zoukankan      html  css  js  c++  java
  • java并发:线程协作机制之CyclicBarrier

    一、初识CyclicBarrier

     

    二、示例

    应用场景:

    在某种需求中,比如一个大型的任务,常常需要分配很多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候就可以选择CyclicBarrier了。

    示例:

    package com.test;
    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    public class CyclicBarrierDemo{
        
        public static void main(String args[]) throws Exception{
            
            CyclicBarrier barrier = new CyclicBarrier(3,new TotalTask());
            
            BillTask worker1 = new BillTask("111",barrier);
            BillTask worker2 = new BillTask("222",barrier);
            BillTask worker3 = new BillTask("333",barrier);
            worker1.start();
            worker2.start();
            worker3.start();
            System.out.println("Main thread end!");
        }
        
        static class TotalTask extends Thread {
            public void run() {
                System.out.println("所有子任务都执行完了,就开始执行主任务了。");
            }
        }
        
        static class BillTask extends Thread {
            private String billName;
            private CyclicBarrier barrier;
    public BillTask(String workerName,CyclicBarrier barrier) { this.billName = workerName; this.barrier = barrier; }
    @Override
    public void run() { try { System.out.println("市区:"+billName +"运算开始:"); Thread.sleep(1000L);//模仿第一次运算; System.out.println("市区:"+billName +"运算完成,等待中..."); barrier.await();//假设一次运算不完,第二次要依赖第一次的运算结果。都到达这个节点之后后面才会继续执行; System.out.println("全部都结束,市区"+billName +"才开始后面的工作。"); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } } }

    上述程序运行结果如下:

    市区:111运算开始:
    市区:333运算开始:
    Main thread end!
    市区:222运算开始:
    市区:333运算完成,等待中...
    市区:222运算完成,等待中...
    市区:111运算完成,等待中...
    所有子任务都执行完了,就开始执行主任务了。//这句话是最后到达wait()方法的那个线程执行的
    全部都结束,市区111才开始后面的工作。
    全部都结束,市区222才开始后面的工作。
    全部都结束,市区333才开始后面的工作。

    解说:

    A、在这个示例中,构造CyclicBarrier时,传入了内部类TotalTask(TotalTask继承了Thread,是Runnable的实现)的实例对象,其意义在于:当所有的线程都执行到wait()方法时,它们会一起返回继续自己的工作,但是最后一个到达wait()方法的线程会执行TotalTask的run()方法;

    B、如果在构造CyclicBarrier时没有传入Runnable的实现对象作为构造参数,则当所有的线程都执行到wait()方法时会直接一起返回继续自己的工作。

    三、详解CyclicBarrier

    (1)CyclicBarrier与CountDownLatch的区别

    A、CountDownLatch的作用是允许1或N个线程等待其他线程完成执行;而CyclicBarrier则是允许N个线程相互等待;
    B、CountDownLatch的计数器无法被重置;而CyclicBarrier的计数器可以被重置后使用,因此它被称为是循环的barrier。

    四、参考资料

    (1)https://www.baeldung.com/java-cyclic-barrier

  • 相关阅读:
    python笔记26(正则表达式、re模块)
    python笔记24(回顾、复习)
    python笔记25(正则表达式课程一)
    python笔记23(面向对象课程五)
    python(leetcode)-1.两数之和
    python(leetcode)-283移动零
    python(leetcode)-66加一问题
    python(leetcode)-350两个数组的交集
    python(leetcode)-136只出现一次的数字
    python数据结构-数组/列表/栈/队列及实现
  • 原文地址:https://www.cnblogs.com/studyLog-share/p/14992703.html
Copyright © 2011-2022 走看看