java并发之同步辅助类CyclicBarrier

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视频获取

原文地址:http://blog.51cto.com/13538361/2088246

时间: 2024-10-09 10:20:28

java并发之同步辅助类CyclicBarrier的相关文章

java并发之同步辅助类Phaser

Phaser含义: 更加复杂和强大的同步辅助类.它允许并发执行多阶段任务.当我们有并发任务并且需要分解成几步执行时,(CyclicBarrier是分成两步),就可以选择使用Phaser.Phaser类机制是在每一步结束的位置对线程进行同步,当所有的线程都完成了这一步,才允许执行下一步.跟其他同步工具一样,必须对Phaser类中参与同步操作的任务数进行初始化,不同的是,可以动态的增加或者减少任务数. 函数:arriveAndAwaitAdvance():类似于CyclicBarrier的await

java并发之同步辅助类CountDownLatch

CountDownLatch 含义: CountDownLatch可以理解为一个计数器在初始化时设置初始值,当一个线程需要等待某些操作先完成时,需要调用await()方法.这个方法让线程进入休眠状态直到等待的所有线程都执行完成.每调用一次countDown()方法内部计数器减1,直到计数器为0时唤醒.这个可以理解为特殊的CyclicBarrier.线程同步点比较特殊,为内部计数器值为0时开始. 方法:核心方法两个:countDown()和await()countDown():使CountDown

java并发之同步辅助类

CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier).它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活.CyclicBarrier默认的构造方法是 CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞. cBarrierTest { public

java并发之同步辅助类semaphore

semaphore(sem??f?r)含义: 信号量就是可以声明多把锁(包括一把锁:此时为互斥信号量).举个例子:一个房间如果只能容纳5个人,多出来的人必须在门外面等着.如何去做呢?一个解决办法就是:房间外面挂着五把钥匙,每进去一个人就取走一把钥匙,没有钥匙的不能进入该房间而是在外面等待.每出来一个人就把钥匙放回原处以方便别人再次进入. 常用方法acquire():获取信号量,信号量内部计数器减1release():释放信号量,信号量内部计数器加1tryAcquire():这个方法试图获取信号量

JAVA线程同步辅助类CyclicBarrier循环屏障

CyclicBarrier是一个同步辅助类,主要作用是让一组线程互相等待,知道都到达一个公共障点,在一起走.在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用.因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier. CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次.若在继续所有参与线程之前更新共享状态,此屏

Java并发之CountDownLatch、CyclicBarrier和Semaphore

CountDownLatch 是能使一组线程等另一组线程都跑完了再继续跑:CyclicBarrier 能够使一组线程在一个时间点上达到同步,可以是一起开始执行全部任务或者一部分任务. 这次说一下 JUC 中的同步器三个主要的成员:CountDownLatch.CyclicBarrier 和 Semaphore(不知道有没有初学者觉得这三个的名字不太好记).这三个是 JUC 中较为常用的同步器,通过它们可以方便地实现很多线程之间协作的功能.(下面的代码出自 JDK 文档) CountDownLat

Java多线程_同步工具CyclicBarrier

CyclicBarrier概念:CyclicBarrier是多线程中的一个同步工具,它允许一组线程互相等待,直到到达某个公共屏障点.形象点儿说,CyclicBarrier就是一个屏障,要求这一组线程中的每一个线程都要等待其他的线程执行完成,即这一组线程全部来到屏障前(全部执行完成),屏障才会打开,放这一组线程全部通过去执行下一个操作. 构造方法: CyclicBarrier(int parties):需要声明需要拦截的线程数: CyclicBarrier(int parties, Runnabl

Java并发编程-同步辅助类之Exchanger

Exchanger是自jdk1.5起开始提供的工具套件,一般用于两个工作线程之间交换数据.在本文中我将采取由浅入深的方式来介绍分析这个工具类.首先我们来看看官方的api文档中的叙述: A synchronization point at which threads can pair and swap elements within pairs. Each thread presents some object on entry to the exchange method, matches wi

【Java多线程】CyclicBarrier同步辅助类

CyclicBarrier是java.util.concurrent包下的一个同步辅助类,类似于CountDownLatch,也是一个同步计数器. 与CountDownLatch不同的区别是:    CountDownLatch的await()方法阻塞的原因是等待调用一定次数的countDown()方法, 可以在同一线程完成; CyclicBarrier的await()方法阻塞的原因是等待一定数量的线程调用await()方法, 必须在不同线程调用 所以,概括来说: CountDownLatch是