文档章节

java并发之同步辅助类CyclicBarrier

happyhuangjinjin
 happyhuangjinjin
发布于 03/18 20:24
字数 864
阅读 11
收藏 5

CyclicBarrier含义:

栅栏允许两个或者多个线程在某个集合点同步。当一个线程到达集合点时,它将调用await()方法等待其它的线程。线程调用await()方法后,CyclicBarrier将阻塞这个线程并将它置入休眠状态等待其它线程的到来。等最后一个线程调用await()方法时,CyclicBarrier将唤醒所有等待的线程然后这些线程将继续执行。CyclicBarrier可以传入另一个Runnable对象作为初始化参数。当所有的线程都到达集合点后,CyclicBarrier类将Runnable对象作为线程执行。

 

方法

await():使线程置入休眠直到最后一个线程的到来之后唤醒所有休眠的线程

 

例子

在矩阵(二维数组)中查找一个指定的数字。矩阵将被分为多个子集,每个子集交给一个线程去查找。当所有线程查找完毕后交给最后的线程汇总结果。

查找类:在一个子集中查找指定数字,找到之后把结果存储后调用await()方法置入休眠等待最后一个线程的到来唤醒

import java.util.List;

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

 

public class Searcher implements Runnable {

 

private  CyclicBarrier barrier;

 

private  int[] submock;

 

private  List<Result> result;

 

private int row;

 

private int searchNmu;

 

public Searcher(int[] submock, List<Result> result,  CyclicBarrier barrier, int row, int searchNmu) {

this.barrier = barrier;

this.submock = submock;

this.result = result;

this.row = row;

this.searchNmu = searchNmu;

}

 

 

@Override

public void run() {

System.out.printf("%s: Processing lines from %d .\n", Thread.currentThread().getName(), row);

for(int i=0; i<submock.length; i++){

if(submock[i] == searchNmu){

Result r = new Result();

r.setRow(row);

r.setCol(i);

result.add(r);

}

}

System.out.printf("%s: Lines processed.\n", Thread.currentThread().getName());

try {

barrier.await();

} catch (InterruptedException e) {

e.printStackTrace();

} catch (BrokenBarrierException e) {

e.printStackTrace();

}

}

}

 

结果类:

 

public class Result {

 

//行

int row;

//列

int col;

 

public int getRow() {

return row;

}

 

public void setRow(int row) {

this.row = row;

}

 

public int getCol() {

return col;

}

 

public void setCol(int col) {

this.col = col;

}

 

}

 

汇总类:汇总每个Searcher找到的结果:

 

import java.util.List;

 

public class Grouper implements Runnable {

 

private List<Result> result;

 

int[][] mock;

 

public Grouper(List<Result> result, int[][] mock) {

this.result = result;

this.mock = mock;

}

 

@Override

public void run() {

System.out.printf("Grouper: Processing results...\n");

for (int i = 0; i < result.size(); i++) {

Result r = result.get(i);

if(r!=null)

System.out.println("mock[" + r.row + "][" + r.col + "]" + mock[r.row][r.col]);

}

System.out.printf("Grouper proccessing end...\n");

}

}

 

主函数,如何把Searcher和Grouper类配合起来呢??

 

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.CyclicBarrier;

 

public class CyclicBarrierMain {

 

public static void main(String[] args) {

// 要找的数据

final int SEARCH = 5;

 

// 矩阵的声明

int[][] mock = { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },

{ 1, 2, 3, 5, 5, 6, 7, 8, 9, 10 },

{ 5, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 

{ 1, 2, 3, 4, 6, 6, 7, 8, 5, 10 }, 

{ 1, 5, 3, 4, 5, 6, 7, 8, 5, 10 },

{ 1, 5, 3, 4, 12, 6, 7, 8, 0, 5 } };

// 查找的线程数

int PARTICIPANTS = mock.length;

List<Result> result = new ArrayList<Result>();

// 汇总线程

Grouper grouper = new Grouper(result, mock);

// 栅栏,传入参数含义:线程同步个数,汇总线程

CyclicBarrier barrier = new CyclicBarrier(PARTICIPANTS, grouper);

 

Searcher searchers[] = new Searcher[PARTICIPANTS];

 

for (int i = 0; i < PARTICIPANTS; i++) {

searchers[i] = new Searcher(mock[i], result, barrier, i, SEARCH);

Thread thread = new Thread(searchers[i]);

thread.start();

}

System.out.printf("Main: The main thread has finished.\n");

}

 

}

 

需要注意的地方

线程完成任务后调用CyclicBarrier的await()方法休眠等待。在所有线程在集合点均到达时,栅栏调用传入的Runnable对象进行最后的执行。

与CountDownLatch的区别:

  • 在所有线程到达集合点后接受一个Runnable类型的对象作为后续的执行

  • 没有显示调用CountDown()方法

  • CountDownLatch一般只能使用一次,CyclicBarrier可以多次使用

应用场景

多个线程做任务,等到达集合点同步后交给后面的线程做汇总

 

海量it视频获取

© 著作权归作者所有

共有 人打赏支持
happyhuangjinjin
粉丝 3
博文 37
码字总数 36961
作品 0
深圳
程序员
私信 提问
java多线程系列:通过对战游戏学习CyclicBarrier

CyclicBarrier是java.util.concurrent包下面的一个工具类,字面意思是可循环使用(Cyclic)的屏障(Barrier),通过它可以实现让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一...

huangzd
01/06
0
0
java障碍器 CyclicBarrier

Java5中,添加了障碍器类,为了适应一种新的设计需求,比如一个大型的任务,常常需要分配好多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候,就可以选择障碍器了。...

古月楼
2013/08/26
0
0
显式锁(java.util.Concurrent)

一、前言   在分析完了集合框架后,很有必要接着分析java并发包下面的源码,JUC(java.util.concurrent)源码也是我们学习Java迈进一步的重要过程。我们分为几个模块进行分析,首先是对锁模...

狼王黄师傅
11/27
0
0
【死磕Java并发】—– 死磕 Java 并发精品合集

【死磕 Java 并发】系列是 LZ 在 2017 年写的第一个死磕系列,一直没有做一个合集,这篇博客则是将整个系列做一个概览。 先来一个总览图: 【高清图,请关注“Java技术驿站”公众号,回复:脑...

chenssy
07/22
0
0
Java多线程打辅助的三个小伙子

之前学多线程的时候没有学习线程的同步工具类(辅助类)。ps:当时觉得暂时用不上,认为是挺高深的知识点就没去管了.. 在前几天,朋友发了一篇比较好的Semaphore文章过来,然后在浏览博客的时候...

Java3y
07/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

使用Laya引擎开发微信小游戏(下)

本文由云+社区发表 6. 动画 6.1 创建伞兵对象 在src目录下创建一个新目录role,用来存放游戏中角色。 在role里创建一个伞兵Soldier.ts对象文件。 module role{ export class Soldier ex...

腾讯云加社区
17分钟前
0
0
移动PWA初探

在去年上海举办的2017谷歌开发者大会上,PWA作为会议的一个重要内容被推介,笔者作为参会嘉宾看了PWA的内容后,觉得这种技术会是未来移动发展的一个趋势。Google开发技术推广工程师Michael Y...

临江仙卜算子
20分钟前
0
0
Git工作原理

git跟传统的代码管理器(如svn)不同, 主要区别在于git多了个本地仓库以及缓存区,所以即使无法联网也一样能提交代码。 术语解释: 工作区间: 即我们创建的工程文件, 在编辑器可直观显示;...

Lienson
23分钟前
2
0
MySQL驱动对应Server版本、JDK版本

昨日生产上线,临时升级MySQL版本,导致连接不上。 应用JDK版本1.5 测试环境MySQL版本5.7 驱动版本5.1.40.jar 正常 生产环境MySQL版本8.0 驱动版本5.1.40.jar 连接不上 生产环境MySQL版本8.0...

zcjlq
25分钟前
11
0
千万级规模【高性能、高并发】互联网架构经验分羹

架构以及我理解中架构的本质 在开始谈我对架构本质的理解之前,先谈谈对今天技术沙龙主题的个人见解,千万级规模的网站感觉数量级是非常大的,对这个数量级我们战略上 要重 视 它 , 战术上又...

java知识分子
25分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部