java并发:线程同步机制之CyclicBarrier

2021/7/10 9:05:56

本文主要是介绍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



这篇关于java并发:线程同步机制之CyclicBarrier的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程