一、应用背景
在实际的应用中,我们有时候需要启动多个线程来完成一项任务,而且要求多个线程在到达某一个点的时候停下来,等待所有的线程都到达这个点之后继续各自向下运行,这时候java.util.concurrent.CyclicBarrier就派上用场了。这里最重要的方法就是 await() ,当所有的线程都调用了该方法之后,这些线程才可以继续向下运行,否则将处于等待,等待所有的线程都调用这个方法。
案例,通过多线程统计一组数据:
package com.sino.thread;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo implements Runnable{
private int count = 0;
private int num;
private CyclicBarrier barrier;
public CyclicBarrierDemo(CyclicBarrier barrier,int num) {
this.barrier = barrier;
this.num = num;
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0; i<num; i++) {
count = count + i;
}
System.out.println(Thread.currentThread().getName());
try {
barrier.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" 累加的和是:"+count);
}
}
测试类:
package com.sino.thread.test;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.sino.thread.CyclicBarrierDemo;
public class CyclicBarrierTest {
public static void main(String[] args) {
Runnable runner = new Runnable(){
@Override
public void run() {
System.out.println("开始计算");
}
};
CyclicBarrier barrier = new CyclicBarrier(2, runner);
CyclicBarrierDemo demo = new CyclicBarrierDemo(barrier,10);
ExecutorService exec = Executors.newFixedThreadPool(2);
Thread t1 = new Thread(demo,"t1");
Thread t2 = new Thread(demo,"t2");
exec.submit(t1);
exec.submit(t2);
exec.shutdown();
}
}
运行的结果:
pool-1-thread-1
pool-1-thread-2
开始计算
pool-1-thread-2 累加的和是:90
pool-1-thread-1 累加的和是:90
二、说明
执行到CyclicBarrier barrier = new CyclicBarrier(2, runner);时
Runnable的参数是在CyclicBarrier的数目达到2时并且所有线程调用.await()进入等待且未被唤醒前执行。 从输出结果可以看到,在两个线程都到达await()之后,才进入到runner对应的run方法中,之后两个线程继续向下执行
所以继续执行下面的两个线程
Thread t1 = new Thread(demo,"t1");
Thread t2 = new Thread(demo,"t2");
执行public void run()方法,分别执行,互不影响
执行到barrier.await();时该线程进入等待状态,当两个线程都执行完barrier.await();时,进入到new CyclicBarrier(2, runner);里面的run方法, 执行完里面的方法后,等待的两个线程再次被唤醒,继续各自执行线程后面的语句。
分享到:
相关推荐
NULL 博文链接:https://hubowei1.iteye.com/blog/2312471
CyclicBarrier的使用以及注意事项
与CountDownLatch不同的是,CyclicBarrier可以重复使用,即当所有线程都到达屏障后,屏障会自动重置,可以继续使用。 CyclicBarrier的构造方法如下: java public CyclicBarrier(int parties, Runnable ...
java并发编程中CountDownLatch和CyclicBarrier的使用.pdf
java并发编程中CountDownLatch和CyclicBarrier的使用借鉴.pdf
《java并发编程》中CountDownLatch和CyclicBarrier用法实例大全,几乎包含了所有重要的用法
主要介绍了Java并发实例之CyclicBarrier的使用,涉及CyclicBarrier的介绍,以及相关的并发实例,具有一定参考价值,需要的朋友可以了解下。
目录: 简介 1.1 并发编程与线程协作 1.2 CyclicBarrier概述 CyclicBarrier的基本用法 2.1 创建CyclicBarrier对象 ...4.2 使用CyclicBarrier循环使用 CyclicBarrier与CountDownLatch的对比 最佳实践与注意事项
主要介绍了java多线程之CyclicBarrier的使用方法的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下
用CyclicBarrier,reentrantlock,condition来完成同时购买,同步购买的功能 JUC系列之模拟抢票(N人同时抢票,票不足系统补仓,N-M人继续抢票) http://blog.csdn.net/crazyzxljing0621/article/details/77891620
CyclicBarrier类似于CountDownLatch也是个计数器,不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数,当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续...
在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时CyclicBarrier很有用。因为该barrier在释放等待线程后可以重用,所以称它为 循环 的barrier。 CyclicBarrier 支持一个可选的 Runnable命令,...
主要为大家详细分析了Java并发系列之CyclicBarrier源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
CyclicBarrier和CountDownLatch一样,都是关于线程的计数器。用法略有不同,测试代码如下:
主要介绍了Java并发编程(CyclicBarrier)实例详解的相关资料,JAVA编写并发程序的时候,我们需要仔细去思考一下并发流程的控制,如何让各个线程之间协作完成某项工作。
CountDownLatch 和 CyclicBarrier 为线程同步的辅助工具,通过它可以做到使一条线程一直阻塞等待,直到其他线程完成其所处理的任务。
CyclicBarrier实现多个线程相互等待的案例(实现累加操作)