CyclicBarrier,通过设置屏障的方式使得多线程同步,能够控制多个线程在屏障处等等其他线程也执行到屏障点,可以实现CountDownLatch具有的功能,但是比CountDownLatch功能强大;
CyclicBarrier即同步屏障,它主要功能是让一组线程达到一个屏障(也可以称为同步点)是被阻塞,直到最后一个线程达到屏障时,屏障才被打开,所有被拦截的线程才会继续执行。
其构造函数默认也是接收一个int类型的参数N作为屏障拦截的线程数量,每个线程调用await方法表示到达了屏障点,然后被阻塞。
具体示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | public class CyclicBarrierTest { // 参数表示屏障拦截的线程数量, 每个线程调用 await方法,告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞 // 屏障拦截的线程数量必须和当前的线程数一致,并且都调用await方法,否则当前所有的线程都处于等待状态 static CyclicBarrier c = new CyclicBarrier( 3 ); public static void main(String[] args) { new Thread( new Runnable() { @Override public void run() { try { System.out.println( "1---1 " + new SimpleDateFormat( "HH:mm:ss" ).format( new Date())); c.await(); } catch (BrokenBarrierException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println( "1---2 " + new SimpleDateFormat( "HH:mm:ss" ).format( new Date())); } }).start(); new Thread( new Runnable() { @Override public void run() { System.out.println( "2---1 " + new SimpleDateFormat( "HH:mm:ss" ).format( new Date())); try { c.await(); } catch (BrokenBarrierException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println( "2---2 " + new SimpleDateFormat( "HH:mm:ss" ).format( new Date())); } }).start(); SleepUtils.second( 2 ); System.out.println( "3---1 " + new SimpleDateFormat( "HH:mm:ss" ).format( new Date())); try { c.await(); } catch (BrokenBarrierException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println( "3---2 " + new SimpleDateFormat( "HH:mm:ss" ).format( new Date())); } } |
输出结果如下:
1 2 3 4 5 6 | 2 --- 1 10 : 03 : 30 1 --- 1 10 : 03 : 30 3 --- 1 10 : 03 : 32 1 --- 2 10 : 03 : 32 2 --- 2 10 : 03 : 32 3 --- 2 10 : 03 : 32 |
注意点
1、构造函数中的N必须为线程的总数,当最后一个线程调用await方法(到达屏障)时,屏障才会打开,被阻塞的线程才会执行,这里的N表示的含义和CountDownLatch传入的N是不一样的。
2、我们发现,当所有线程都到达屏障时,当屏障打开,接下来会优先执行哪个线程呢?如上代码答案是不确定的。但是CyclicBarrier为我们提供了一个更高级的用法,即构造函数还支持传递一个Runnable对象,当屏障打开时,优先执行Runnable中的run方法。(这一功能十分强大,完全可以替代CountDownLatch了)
应用场景
同CountDownLatch
与CountDownLatch区别:
CountDownLatch计数器只能使用一次,而CyclicBarrier的计数器可以使用 reset方法重置,所以适合更复杂的业务场景。
参考: https://blog.csdn.net/qq_27828675/article/details/114068266
作者:Work Hard Work Smart
出处:http://www.cnblogs.com/linlf03/
欢迎任何形式的转载,未经作者同意,请保留此段声明!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
2020-04-12 java子线程中获取父线程的threadLocal中的值
2020-04-12 String源码解析