码迷,mamicode.com
首页 > 编程语言 > 详细

java并发之同步辅助类CyclicBarrier

时间:2018-03-18 20:38:47      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:java   多线程   

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

技术分享图片

java并发之同步辅助类CyclicBarrier

标签:java   多线程   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!