2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 一心多用多线程-阻塞队列(7)-CyclicBarrier

一心多用多线程-阻塞队列(7)-CyclicBarrier

时间:2022-08-24 18:18:01

相关推荐

一心多用多线程-阻塞队列(7)-CyclicBarrier

七、都做好了了就一起执行-CyclicBarrier

在文章(6)中我们谈到一个现象,就是做一道菜有时候是会分出多个工序进行的,当每个工序做好了之后那到菜才能相应的被做出来。文章(6)使用的是CountDownLatch,是通过线程间调用倒数的机制实现线程间的交流通知的,而今天学习到的CyclicBarrier作用类似于CountDownLatch,但CyclicBarrier没有倒数机制。

CyclicBarrier按字面的意思理解就是循环栅栏,它的作用机制是这样的,它可以定义一个阀限定线程数比如为2。给出两条线程,线程里面执行代码区域调用栅栏的await方法,相当于给代码区画了一条线,当这两条线程中任意一方先执行到抵达await方法时,会进行等待,直到两条线程都执行抵达await方法时,两者才能共同继续向下执行。

CyclicBarrier给出两个构造函数

CyclicBarrier(int parties) 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在启动 barrier 时执行预定义的操作。 CyclicBarrier(int parties, Runnable barrierAction) 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。

第二个方法与第一个方法区别在于可以传入一个Runnable作为启动栅栏时的操作,即当所有线程都达到栅栏点时,会先调用该Runnable执行之后所有其他线程才继续往下执行,下面根据代码了解一下具体的作用。

public class CyclicBarrierTest {public static void main(String[] args) {CyclicBarrier valve = new CyclicBarrier(2, new Runnable() {@Overridepublic void run() {System.out.println("各道工序准备好了,制作肠粉");}});Thread caiOffer = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("准备" + "白菜");try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("白菜准备好了,等待中");try {valve.await();} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}System.out.println("白菜师傅" + "工作结束");}});Thread fenOffer = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("准备" + "粉皮");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("粉皮准备好了,等待中");try {valve.await();} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}System.out.println("粉皮师傅" + "工作结束");}});fenOffer.start();caiOffer.start();}}

结果:

准备粉皮准备白菜白菜准备好了,等待中粉皮准备好了,等待中各道工序准备好了,制作肠粉粉皮师傅工作结束白菜师傅工作结束

由上面的结果可以看出,“粉皮师傅”与“白菜师傅”是同时开始作业的,但是“白菜师傅”工作比“粉皮师傅”工作先手完成,然后“白菜师傅”进行等待,等待“粉皮师傅”完成工作之后再一齐往下执行。两个师傅同时完成工作时,传入到循环栅栏构造器里面的Runnable被触动,会在两个“师傅”完成剩下工作前执行调用,所以会先出现“各道工序准备好了,制作肠粉”等句式。

在demo的过程中假设CyclicBarrier valve = new CyclicBarrier(2),但此时只有一个线程调用await方法,那么该线程会一直等待,因为没有另一个线程执行await,所以这里构造栅栏定义线程数的时候线程量一定要与执行的线程量相等或执行线程量是定义线程数的倍数,否则程序将会不断等待。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。