CyclicBarrier
用于多线程计算数据,最后合并计算结果的应用场景
CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)
它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。
CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。
CyclicBarrier还提供其他有用的方法,比如getNumberWaiting方法可以获得CyclicBarrier阻塞的线程数量。
CyclicBarrier和CountDownLatch的区别
- CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次。
- CyclicBarrier强调的是n个线程,大家相互等待,只要有一个没完成,所有人都得等着
countdownlatch:
场景:
doJob();
countDownLatch.countDown(); //表示任务完成了
afterJob();// 一般后续没有代码,如果有则逻辑会比较乱,不建议使用countdownlatch。
cyclicBarrier:
场景:
doJob();
cyclicBarrier.await(); // 通知CyclicBarrier,我到达了同步点,线程挂起,暂停执行。
afterJob();// 这部分在其余线程都到达同步点后,继续执行。
import java.util.concurrent.CountDownLatch; public class TestCountDownLantch { // 等待三个任务线程通知执行完成
static CountDownLatch cdl = new CountDownLatch(3); public static void main(String[] args) { for(int i=0; i<3; i++){
new Thread(new worker(i, cdl)).start();
} try {
System.out.println("wait for work threads...");
cdl.await();
System.out.println("OK! all threads done. I can do something...->>");
} catch (InterruptedException e) {
e.printStackTrace();
}
} static class worker implements Runnable{
private final int id;
private CountDownLatch cdl; public worker(int id, CountDownLatch cdl){
this.id = id;
this.cdl = cdl;
} @Override
public void run(){
try {
System.out.println(id+" working...");
Thread.sleep(id*2000+10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println(id+" done.");
cdl.countDown();
System.out.println(id+" going on...");
}
}
}
wait for work threads...
0 working...
2 working...
1 working...
0 going on...
0 done.
1 done.
1 going on...
2 done.
2 going on...
OK! all threads done. I can do something...->>
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; public class TestCyclicBarrier { public static void main(String[] args) { CyclicBarrier cBarrier = new CyclicBarrier(3, new Runnable() { @Override
public void run() {
System.out.println("OK! all threads done. let's go! ->>>");
}
}); for(int i=0; i<3; i++){
new Thread(new workThread(i, cBarrier)).start();
}
} static class workThread implements Runnable{
private final int id;
private CyclicBarrier cBarrier; public workThread(int id, CyclicBarrier barrier) {
this.id = id;
cBarrier = barrier;
} @Override
public void run() {
try {
System.out.println("thread " + id + " working...");
Thread.sleep(id*1000+10);
System.out.println("thread " + id + " done.");
cBarrier.await();
System.out.println("thread " + id + " going on...");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
} } }
thread 0 working...
thread 2 working...
thread 1 working...
thread 0 done.
thread 1 done.
thread 2 done.
OK! all threads done. let's go! ->>>
thread 0 going on...
thread 1 going on...
thread 2 going on...
Thread.join() 等待该线程终止信号
在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,
但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,
这个时候就要用到join()方法了
public class TestJoin { static Thread[] threads = new Thread[5]; public static void main(String[] args) {
System.out.println("waiting all thread work done..."); for(int i=0; i<5; i++){
Thread t = new Thread(new workerThread(i));
t.start();
threads[i] = t;
} for(Thread t : threads){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} System.out.println("main going on...");
} static class workerThread implements Runnable{
final int id;
public workerThread(int id) {
this.id = id;
} @Override
public void run() {
try {
System.out.println(id+" working...");
Thread.sleep(id*2000+10);
System.out.println(id+" done.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
waiting all thread work done...
1 working...
3 working...
0 working...
2 working...
4 working...
0 done.
1 done.
2 done.
3 done.
4 done.
main going on...
http://ifeve.com/concurrency-cyclicbarrier/#header
CyclicBarrier的更多相关文章
- 【Java并发编程实战】-----“J.U.C”:CyclicBarrier
在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...
- 多线程条件通行工具——CyclicBarrier
CyclicBarrier的作用是,线程进入等待后,需要达到一定数量的等待线程后,再一次性开放通行. CyclicBarrier(int, Runnable)构造方法,参数1为通行所需的线程数量,参数 ...
- java多线程--同步屏障CyclicBarrier的使用
CyclicBarrier的概念理解: CyclicBarrier的字面上的意思是可循环的屏障,是java并发包java.util.concurrent 里的一个同步工具类,在我下载的JDK1.6的中 ...
- 架构师养成记--12.Concurrent工具类CyclicBarrier和CountDownLatch
java.util.concurrent.CyclicBarrier 一组线程共同等待,直到达到一个公共屏障点. 举个栗子,百米赛跑中,所有运动员都要等其他运动员都准备好后才能一起跑(假如没有发令员) ...
- java并发编程(十九)障碍器CyclicBarrier
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17512983 CyclicBarrier(又叫障碍器)同样是Java 5中加入的新特性,使 ...
- Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例
概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...
- 【JUC】JDK1.8源码分析之CyclicBarrier(四)
一.前言 有了前面分析的基础,现在,接着分析CyclicBarrier源码,CyclicBarrier类在进行多线程编程时使用很多,比如,你希望创建一组任务,它们并行执行工作,然后在进行下一个步骤之前 ...
- CyclicBarrier ------仿真赛马游戏
import java.util.ArrayList;import java.util.List;import java.util.Random;import java.util.concurrent ...
- java并发编程学习:如何等待多个线程执行完成后再继续后续处理(synchronized、join、FutureTask、CyclicBarrier)
多线程应用中,经常会遇到这种场景:后面的处理,依赖前面的N个线程的处理结果,必须等前面的线程执行完毕后,后面的代码才允许执行. 在我不知道CyclicBarrier之前,最容易想到的就是放置一个公用的 ...
- CountDownLatch和CyclicBarrier 举例详解
有时候会有这样的需求,多个线程同时工作,然后其中几个可以随意并发执行,但有一个线程需要等其他线程工作结束后,才能开始.举个例子,开启多个线程分块下载一个大文件,每个线程只下载固定的一截,最后由另外一个 ...
随机推荐
- 关于web.config中customErrors
<customErrors>节点用于定义一些自定义错误信息的信息.此节点有Mode和defaultRedirect两个属性,其中defaultRedirect属性是一个可选属性,表示应用程 ...
- [Asp.net]说说密码框和只读框
作者:Wolfy出处:http://www.cnblogs.com/wolf-sun/ 引言 最近负责了一个公司的小项目,从前台到后代,都是自己搞的,为一个客户弄一个信息管理的小系统,虽然对界面什么的 ...
- Android学习笔记1 android adb启动失败问题 adb server is out of date. killing...
下面是Android的学习笔记,原文地址. 我是使用adb devices出现如下红字错误, 使用第一种方法方法,结果关掉豌豆荚就可以了. android adb启动失败问题 adb server i ...
- [spring] java.lang.reflect.MalformedParameterizedTypeException
spring中加入dubbo后报java.lang.reflect.MalformedParameterizedTypeException 因为dubbo 2.5.3 它引用的是spring 2.5. ...
- 计算阶乘n!末尾0的个数
一.问题描述 给定一个正整数n,请计算n的阶乘n!末尾所含有“0”的个数.例如: 5!=120,其末尾所含有的“0”的个数为1: 10!= 3628800,其末尾所含有的“0”的个数为2: 20!= ...
- Slow HTTP Denial of Service Attack
整改建议 1.中断使用URL不支持HTTP方法访问的会话 2.限制HTTP头及包长至一个合理数值 3.设置一个绝对的会话超时时间 4.服务器支持backlog的情况下,需设置一个合理的大小 5.设置一 ...
- ettercap ARP dns 欺骗
1.arp 这个简单,太熟了.略过1 2.dns 根据arp欺骗的步骤. 多了个etter.dns文件 找到它:locate etter.dns 进入后添加dns正向解析 启动,选 ...
- bzoj1760 [Baltic2009]Triangulation
给定一个多边形的三角剖分(n<=1e5),且每个三角形有其颜色,问最多可以把这个三角剖分分成几个联通的部分,使任何一种颜色不出现在多个连通块中 建出三角剖分对应的树,同种颜色的点之间的路径是不能 ...
- HDU 3480 division
题目大意:一个有n个数的集合,现在要求将他分成m+1个子集,对子集i设si表示该集合中最大数与最小数的差的平方.求所有si的和的最小值.n<=10000,m<=5000. 分析:最优解的m ...
- 【maven】之使用jetty发布web项目
<plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin ...