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

  • 相关阅读:
    Django中文无法转换成latin-1编码的解决方案
    JS-排序详解:冒泡排序、选择排序和快速排序
    javascript实例
    selenium webdriver 启动三大浏览器Firefox,Chrome,IE
    javascript教程5:--BOM操作
    python----图像简单处理(PIL or Pillow)
    Python模块学习之bs4
    采集淘宝美人库
    JavaScript 中的FileReader对象(实现上传图片预览)
    WPF
  • 原文地址:https://www.cnblogs.com/studyLog-share/p/14992703.html
Copyright © 2011-2022 走看看