Java并发工具类之同步屏障CyclicBarrier
CyclicBarrier的字面意思是可以循环使用的Barrier,它要做的事情是让一个线程到达一个Barrier的时候被阻塞,直到最后一个线程到达Barrier,屏障才会放开,所有被Barrier拦截的线程才会继续运行。
CyclicBarrier的默认的构造器是CyclicBarrier(int parties),参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。示例代码如下:
public class CyclicBarrierTest { private static CyclicBarrier barrier = new CyclicBarrier(2); public static void main(String[] args) throws BrokenBarrierException, InterruptedException { new Thread(new Runnable() { @Override
public void run() {
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.print("thread1");
} }).start(); barrier.await(); System.out.println("mainThread");
}
}
因为子线程和主线程的调度由CPU决定,每个线程都有可能优先执行,因此会产生两种不同的结果,可能的结果如下:
mainThread
thread1
如果把CyclicBarrier的Barrier的个数由2改为3,则主线程和子线程会永远等待,因为没有第三个线程执行await方法,即没有第三个线程到达屏障,因此之前到达屏障的两个线程都不会继续执行。
CyclicBarrier还提供了一个高级的构造器,CyclicBarrier(int parties, Runnable barrierAction),用于在线程到达屏障后,优先执行barrierAction线程里面的逻辑。比如有如下的场景,在所有的线程都处理完成后,打印“All Done”,可以参考如下代码:
public class CyclicBarrierTest2 { private static CyclicBarrier barrier = new CyclicBarrier(2,new DoneThread()); public static void main(String[] args) throws BrokenBarrierException, InterruptedException { new Thread(new Runnable() { @Override
public void run() { System.out.println("thread1");
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
} }).start(); System.out.println("mainThread");
barrier.await();
} static class DoneThread implements Runnable{ @Override
public void run() {
System.out.println("All Done");
} }
}
输出结果如下:
mainThread
thread1
All Done
因此CyclicBarrier常用于处理,多线程计算最后合并计算结果的场景。
CyclicBarrier和CountDownLatch的区别:
1.CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset方法重置,因此CyclicBarrier可以处理线程计算出错时重复计算的场景。
2.CyclicBarrier还提供了别的有用的方法,如getNumberWaiting可以获得等待的线程数,isBroken方法可以了解阻塞的线程是否被中断等。
最新文章
- 移动UI设计
- 字符串反转----将this is good 转化为good is this 输出。
- ldap配置记录
- 使用jquery-qrcode生成二维码
- 一个ubuntu phper的自我修养(ubuntu安装)
- resolv.conf
- C#实现Excel的导入导出
- 决策树之C4.5算法
- Form认证导致登陆页面的样式无效和图片不能显示的原因
- 一种基于C51单片机的非抢占式的操作系统架构
- 【python】自定义函数def funName():
- Spring boot(三)整合mybaties+thymeleaf实现基础crud
- Java多线程处理某个线程超时的问题
- STLINK V2安装使用详解
- 最全的maven的pom.xml文件详解
- OpenGL开发学习指南二(glfw+glad)
- Map Wiki -- proposed by Shuo Ren
- 到底该用img还是background-image?
- scala 读取文件加下的指定文件
- 华为S5300系列交换机V100R006SPH019升级补丁
热门文章
- 201621123008 《Java程序设计》第六周实验总结
- Codeforces 689C. Mike and Chocolate Thieves 二分
- ";UX";将会是下一个Buzzword?
- vue的过滤器
- HRegionServer异常下线问题
- 关于对象的 width offsetwidth availWidth scrollHeight
- PacBio下机数据如何看?
- jQuery 插件使用记录
- 657. Judge Route Circle
- 2018.09.20 atcoder Building Cubes with AtCoDeer(枚举)