Java--CyclicBarrier使用简介
CyclicBarrier介绍 (一)
一
个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier
point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier
在释放等待线程后可以重用,所以称它为循环 的 barrier。CyclicBarrier 支持一个可选的 Runnable
命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作
很有用。
主要使用方法:
//设置parties、count及barrierCommand属性。
CyclicBarrier(int): //当await的数量到达了设定的数量后,首先执行该Runnable对象。
CyclicBarrier(int,Runnable): //通知barrier已完成线程
await():
应用场景
在某种需求中,比如一个大型的任务,常常需要分配好多子任务去执行,只有当所有子任务都执行完成时候,才能执行 主任务,这时候,就可以选择CyclicBarrier了。
实例分析
我们需要统计全国的业务数据。其中各省的数据库是独立的,也就是说按省分库。并且统计的数据量很大,统计过程也比较慢。为了提高性能,快速计算。我们采取并发的方式,多个线程同时计算各省数据,最后再汇总统计。在这里CyclicBarrier就非常有用。看代码:
主要类:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; import utils.Tools.BillService;
import utils.Tools.TotalService; /**
* 各省数据独立,分库存偖。为了提高计算性能,统计时采用每个省开一个线程先计算单省结果,最后汇总。
*
*/
public class Total { // private ConcurrentHashMap result = new ConcurrentHashMap(); public static void main(String[] args) {
TotalService totalService = new TotalServiceImpl();
CyclicBarrier barrier = new CyclicBarrier(5,
new TotalTask(totalService)); // 实际系统是查出所有省编码code的列表,然后循环,每个code生成一个线程。
new BillTask(new BillServiceImpl(), barrier, "北京").start();
new BillTask(new BillServiceImpl(), barrier, "上海").start();
new BillTask(new BillServiceImpl(), barrier, "广西").start();
new BillTask(new BillServiceImpl(), barrier, "四川").start();
new BillTask(new BillServiceImpl(), barrier, "黑龙江").start(); }
} /**
* 主任务:汇总任务
*/
class TotalTask implements Runnable {
private TotalService totalService; TotalTask(TotalService totalService) {
this.totalService = totalService;
} public void run() {
// 读取内存中各省的数据汇总,过程略。
totalService.count();
System.out.println("=======================================");
System.out.println("开始全国汇总");
}
} /**
* 子任务:计费任务
*/
class BillTask extends Thread {
// 计费服务
private BillService billService;
private CyclicBarrier barrier;
// 代码,按省代码分类,各省数据库独立。
private String code; BillTask(BillService billService, CyclicBarrier barrier, String code) {
this.billService = billService;
this.barrier = barrier;
this.code = code;
} public void run() {
System.out.println("开始计算--" + code + "省--数据!");
billService.bill(code);
// 把bill方法结果存入内存,如ConcurrentHashMap,vector等,代码略
System.out.println(code + "省已经计算完成,并通知汇总Service!");
try {
// 通知barrier已经完成
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
} }
import utils.Tools.BillService;
public class BillServiceImpl implements BillService {
@Override
public void bill(String code) {
// TODO Auto-generated method stub
}
}
import utils.Tools.TotalService;
public class TotalServiceImpl implements TotalService{
@Override
public void count() {
// TODO Auto-generated method stub
}
}
package utils;
public class Tools {
/**
*
*/
public interface BillService {
/**
* 各省计费
*
* @param code
* 省编码
*/
public void bill(String code);
}
/**
*
*/
public interface TotalService {
/**
* 汇总各省数据
*/
public void count();
}
}
结果:
开始计算--北京省--数据!
开始计算--四川省--数据!
开始计算--黑龙江省--数据!
开始计算--上海省--数据!
开始计算--广西省--数据!
上海省已经计算完成,并通知汇总Service!
黑龙江省已经计算完成,并通知汇总Service!
四川省已经计算完成,并通知汇总Service!
北京省已经计算完成,并通知汇总Service!
广西省已经计算完成,并通知汇总Service!
=======================================
开始全国汇总
CyclicBarrier介绍 (二)
张孝祥视频学习笔记:
CyclicBarrier 表示大家彼此等待,大家集合好后才开始出发,分散活动后又在i指定地点集合碰面,这就好比整个公司的人员利用周末时间集体郊游一样,先各自从家出发到公司集合后,再同时出发到公园游玩,在指定地点集合后再同时开始就餐……
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class CyclicBarrierTest {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
final CyclicBarrier cb = new CyclicBarrier(3); // 三个线程同时到达
for (int i = 0; i < 3; i++) {
Runnable runnable = new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程"
+ Thread.currentThread().getName()
+ "即将到达集合地点1,当前已有"
+ (cb.getNumberWaiting() + 1)
+ "个已到达"
+ (cb.getNumberWaiting() == 2 ? "都到齐了,继续走啊"
: "正在等候"));
try {
cb.await();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程"
+ Thread.currentThread().getName()
+ "即将到达集合地点2,当前已有"
+ (cb.getNumberWaiting() + 1)
+ "个已到达"
+ (cb.getNumberWaiting() == 2 ? "都到齐了,继续走啊"
: "正在等候"));
try {
cb.await();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程"
+ Thread.currentThread().getName()
+ "即将到达集合地点3,当前已有"
+ (cb.getNumberWaiting() + 1)
+ "个已到达"
+ (cb.getNumberWaiting() == 2 ? "都到齐了,继续走啊"
: "正在等候"));
try {
cb.await();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}
输出结果
线程pool-1-thread-3即将到达集合地点1,当前已有1个已到达正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有2个已到达正在等候
线程pool-1-thread-1即将到达集合地点1,当前已有3个已到达都到齐了,继续走啊
线程pool-1-thread-1即将到达集合地点2,当前已有1个已到达正在等候
线程pool-1-thread-2即将到达集合地点2,当前已有2个已到达正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有3个已到达都到齐了,继续走啊
线程pool-1-thread-3即将到达集合地点3,当前已有1个已到达正在等候
线程pool-1-thread-1即将到达集合地点3,当前已有2个已到达正在等候
线程pool-1-thread-2即将到达集合地点3,当前已有3个已到达都到齐了,继续走啊
CyclicBarrier介绍 (三)
旅游,导游带队,只有在全部成员到齐的时候,导游才会下达去下一个景点的通知。
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class Travel {
private static final int THREAD_COUNT = 3;
// 当THREAD_COUNT 逐个减到0的时候,就开是执行runnable
private final static CyclicBarrier CYSLIC_BARRIER = new CyclicBarrier(
THREAD_COUNT, new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
System.out.println("我是导游,本次点名结束,准备下一个景点。");
}
}); public static void main(String[] args) {
// TODO Auto-generated method stub
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < THREAD_COUNT; i++) {
new Thread(String.valueOf(i)){
public void run() {
try {
System.out.println("我是线程"+ this.getName()+",我们到达旅游景点。");
CYSLIC_BARRIER.await();
System.out.println("我是线程"+ this.getName()+",我们开始骑车。");
CYSLIC_BARRIER.await();
System.out.println("我是线程"+ this.getName()+",我们开始爬山。");
CYSLIC_BARRIER.await();
System.out.println("我是线程"+ this.getName()+",我们回宾馆休息。");
CYSLIC_BARRIER.await();
System.out.println("我是线程"+ this.getName()+",我们骑车回家。");
CYSLIC_BARRIER.await();
System.out.println("我是线程"+ this.getName()+",我们到家了。");
CYSLIC_BARRIER.await();
} catch (Exception e) {
// TODO: handle exception
}
};
}.start();
}
} }
结果:
我是线程2,我们到达旅游景点。
我是线程0,我们到达旅游景点。
我是线程1,我们到达旅游景点。
我是导游,本次点名结束,准备下一个景点。
我是线程1,我们开始骑车。
我是线程0,我们开始骑车。
我是线程2,我们开始骑车。
我是导游,本次点名结束,准备下一个景点。
我是线程2,我们开始爬山。
我是线程0,我们开始爬山。
我是线程1,我们开始爬山。
我是导游,本次点名结束,准备下一个景点。
我是线程1,我们回宾馆休息。
我是线程0,我们回宾馆休息。
我是线程2,我们回宾馆休息。
我是导游,本次点名结束,准备下一个景点。
我是线程2,我们骑车回家。
我是线程0,我们骑车回家。
我是线程1,我们骑车回家。
我是导游,本次点名结束,准备下一个景点。
我是线程1,我们到家了。
我是线程0,我们到家了。
我是线程2,我们到家了。
我是导游,本次点名结束,准备下一个景点。
Java--CyclicBarrier使用简介的更多相关文章
- java.util.concurrent简介
文章目录 主要的组件 Executor ExecutorService ScheduledExecutorService Future CountDownLatch CyclicBarrier Sem ...
- [java] jsoup使用简介-汇率换算器实现-插曲2
[java] jsoup使用简介-汇率换算器实现-插曲2 // */ // ]]> [java] jsoup使用简介-汇率换算器实现-插曲2 Table of Contents 1 系列文章 ...
- Java Servlet 技术简介
Java Servlet 技术简介 Java 开发人员兼培训师 Roy Miller 将我们现有的 servlet 介绍资料修改成了这篇易于学习的实用教程.Roy 将介绍并解释 servlet 是什么 ...
- Java基础类库简介
Java基础类库简介 一.常用的基础类库:11个jar(Java Archive,Java归档)包 作为java语言使用者,我们可以感受到java语言带来的优势(平台无关.面向对象.多线程.高效易扩展 ...
- Java多线程概念简介 多线程中篇(一)
Java的线程与操作系统的线程 在线程的相关介绍中,有讲到“线程的实现”分为三种:内核支持,用户级以及两者混合.(这只是一种简要的分类) Java线程在JDK1.2之前,是用户线程实现的 而在JD ...
- Java编译器API简介
今天给大家分享的是Java编译器API简介,文章部分内容摘自[优锐课]学习笔记. Java编译器API Java编译器API是Java模块(称为java.compiler)的一部分.该模块包括语言模型 ...
- java.math包简介
java.math包提供了java中的数学类 包括基本的浮点库.复杂运算以及任意精度的数据运算 '可以看得到,主要包括三个类一个枚举 BigDecimal和BigInteger接下来会详细介绍 先 ...
- java CyclicBarrier同步屏障
CyclicBarrier的字面意思是可循环使用的屏障,它的主要作用是,让一组线程到达一个屏障时被阻塞,知道最后一个线程到达屏障时,屏障才会打开,所有被屏障拦截的线程才会继续运行. 1.简介: Cyc ...
- Java集合容器简介
Java集合容器主要有以下几类: 1,内置容器:数组 2,list容器:Vetor,Stack,ArrayList,LinkedList, CopyOnWriteArrayList(1.5),Attr ...
- java CyclicBarrier 2
//Listing 6-2. Using a Cyclic Barrier to Decompose a Task into Subtasks import java.util.concurrent. ...
随机推荐
- SGU 202 The Towers of Hanoi Revisited (DP+递归)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题意 :n个圆盘,m个柱子的汉诺塔输出步骤. ht ...
- CSS的z-index(分层)
z-index是针对网页显示中的一个特殊属性.因为显示器是显示的图案是一个二维平面,拥有x轴和y轴来表示位置属性.为了表示三维立体的概念如显示元素的上下层的叠加顺序引入了z-index属性来表示z轴的 ...
- Tomcat7.0.22在Windows下详细配置过程
Tomcat7.0.22在Windows下详细配置过程 一.JDK1.7安装 1.下载jdk,下载地址:http://www.oracle.com/technetwork/java/javase/do ...
- CURL采集
<?php $url='';//输入'网址 $ch = curl_init(); $timeout = 5;//超时时间 curl_setopt ($ch, CURLOPT_URL, $url) ...
- 我在北京找工作(二):java实现算法<1> 冒泡排序+直接选择排序
工作.工作.找工作.经过1个多星期的思想斗争还是决定了找JAVA方面的工作,因为好像能比PHP的工资高点.呵呵 :-) (其实我这是笑脸,什么QQ输入法,模拟表情都没有,忒不人性化了.) 言归正传, ...
- BZOJ 1613: [Usaco2007 Jan]Running贝茜的晨练计划
题目 1613: [Usaco2007 Jan]Running贝茜的晨练计划 Time Limit: 5 Sec Memory Limit: 64 MB Description 奶牛们打算通过锻炼来 ...
- BootStrap - 时间组件
效果: CSS代码: JS代码: 调用:
- ThinkPHP - 连贯操作 - 【实现机制】
<?php //模型类 class Model { //数据库连接 private $_conn = NULL; //where语句 private $_where = NULL; //表名称 ...
- E - Phone List(字典序,string类型使用)
Description Given a list of phone numbers, determine if it is consistent in the sense that no number ...
- [转]组合数取模 Lucas定理
对于C(n, m) mod p.这里的n,m,p(p为素数)都很大的情况.就不能再用C(n, m) = C(n - 1,m) + C(n - 1, m - 1)的公式递推了. 这里用到Lusac定理 ...