多线程并发之CyclicBarrier学习笔记

CyclicBarrier是一个同步工具类

作用:它允许一组线程之间互相等待,直到最后一个线程到达屏障后,所有线程继续执行。

原理:通过一个计数器实现,计数器的初始化值等于线程数量。当一个线程到达屏障后,计数器减一。当计数器为0时,屏障打开,所有线程继续执行。

主要涉及方法:await() 让线程等待,并将计数器减一

举例:假设有4个工作线程,代码如下

public class UseCyclicBarrier {
	
	private static CyclicBarrier barrier = new CyclicBarrier(4);//计数器设置为4
	
    //工作线程
    private static class SubThread implements Runnable{
        @Override
        public void run() {
            try {               
                System.out.println(Thread.currentThread().getId()+"工作线程,进行工作");
                barrier.await();//到达屏障,线程进行等待
                System.out.println(Thread.currentThread().getId()+"工作线程,其他业务");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        for(int i=0;i<=3;i++){
            Thread thread = new Thread(new SubThread());
            thread.start();
        }
    }
}

在主线程中我们调用了四个工作线程,当这四个工作线程运行到barrier.await();时就会进行等待,直到最后一个线程也到达后,所有线程继续执行,运行结果如下:

同样是并发工具类,CyclicBarrier和CountDownLatch有什么区别呢?

一、CountDownLatch的放行条件是外部线程控制,而CyclicBarrier的放行条件是该组线程自己控制,即最后一个线程到达屏障

二、CountDownLatch计数器大于等于线程数,而CyclicBarrier计数器等于线程数

三、CountDownLatch计数器减一需要手动调用countDown(),而CyclicBarrier的await()中自带减一

四、CyclicBarrier的构造函数,可初始化计数器值的同时传入一个Runnable参数,当屏障打开后,自动调用该线程。即CyclicBarrier(int parties, Runnable barrierAction)

还是上面那个例子,加入一个Runnable参数

public class UseCyclicBarrier {
	
	private static CyclicBarrier barrier 
		= new CyclicBarrier(4,new CollectThread());//初始化计数器值,以及传入一个Runnable参数
    
    //负责屏障开放以后的工作
    private static class CollectThread implements Runnable{
        @Override
        public void run() {
            System.out.println("屏障打开后自动调用本线程");
        }
    }

    //工作线程
    private static class SubThread implements Runnable{

        @Override
        public void run() {
            try {
               
                System.out.println(Thread.currentThread().getId()+"工作线程,进行工作");
                barrier.await();//到达屏障,线程进行等待
                System.out.println(Thread.currentThread().getId()+"工作线程,其他业务");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        for(int i=0;i<=3;i++){
            Thread thread = new Thread(new SubThread());
            thread.start();
        }

    }
 
}

 

执行结果如下

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值