博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(三)线程同步工具集_4---在一个约定点同步任务
阅读量:6323 次
发布时间:2019-06-22

本文共 4208 字,大约阅读时间需要 14 分钟。

hot3.png

在一个约定点同步任务(Synchronizing tasks in a  common point)

Java 并发API中提供了一个同步工具CyclicBarrier类可以使多个线程在约定点进行任务同步,该类和CountDownLatch类有点类似,CountDownLatch是等待多个并发事件,在上节有解释;

CyclicBarrier类初始化有两个参数,第一个是要同步的线程个数,第二个要同步的任务(该参数实现了Runnable接口);当这些要同步的线程到达到了这个约定的同步点,它将调用await()方法进入睡眠状态,当所有要同步的线程都到达了这个约定的点后,CyclicBarrier将会唤醒所有睡眠的这些线程,然后执行要同步的任务(传入的第二个参数);

CyclicBarrier最好的就是它可以传入一个实现了Runnable接口的对象,在所有线程到达约定点后,在执行这个对象;这个特性非常适合分治算法 的思想;

再接下来的例子中,简单的使用CyclicBarrier模拟一个简单的分治算法;

问题:即模拟一个矩阵,从该矩阵中查找一个给定的数,并统计该数值在该矩阵中出现的次数;

解决思路:

开启多个线程,每个线程负责查找若干行,并把每一行该数值出现的次数放置到一个数组中,作为结果,每行对应与该数组的索引;在所有线程都查找完成后,执行同步任务,这里仅仅简单的输出最终的结果;

动手实现

1.辅助类,用来模拟矩阵

public class MatrixMock {    private int data[][];    public MatrixMock(int rows,int cols,int number){        int counter=0;        data=new int[rows][cols];        Random random=new Random();        for (int i = 0; i < rows; i++) {            for(int j=0;j
= 0) && (row < data.length)) { return data[row]; } return null; }}
2.辅助类,用来放置每个线程处理结果,索引对应矩阵行数,列对应每行查找到指定数值的次数

public class Result {    private int data[];    public Result(int size) {        this.data = new int[size];    }    public void setData(int position,int value){        data[position]=value;    }    public int[] getData(){        return data;    }}
3.用来执行计算的线程

public class Searcher implements Runnable {    private int firstRow;    private int lastRow;    private MatrixMock mock;    private Result result;    private int number;    private final CyclicBarrier barrier;    public Searcher(int firstRow, int lastRow, MatrixMock mock, Result result,                    int number, CyclicBarrier barrier) {        this.firstRow = firstRow;        this.lastRow = lastRow;        this.mock = mock;        this.result = result;        this.number = number;        this.barrier = barrier;    }    @Override    public void run() {        int counter;        System.out.printf("%s: Processing lines from %d to %d.\n",                Thread.currentThread().getName(), firstRow, lastRow);        for (int i = firstRow; i < lastRow; i++) {            int row[] = mock.getRow(i);            counter = 0;            for (int j = 0; j < row.length; j++) {                if (row[j] == number) {                    counter++;                }            }            result.setData(i, counter);        }        System.out.printf("%s: Lines processed.\n", Thread.currentThread().getName());        try {            barrier.await();        } catch (BrokenBarrierException | InterruptedException e) {            e.printStackTrace();        }    }}
4.同步任务,当所有线程完成之后执行,类似于分治算法中的
结果合并

public class Grouper implements Runnable {    private Result result;    public Grouper(Result result) {        this.result = result;    }    @Override    public void run() {        int finalResult=0;        System.out.printf("Grouper: Processing results...\n");        int data[]=result.getData();        for(int number:data){            finalResult+=number;        }        System.out.printf("Grouper: Total result: %d.\n",finalResult);    }}
5.Main

public class Main {    public static void main(String[] args) {        final int rows=10000;        final int cols=1000;        final int search=5;        final int participants=5;        final int linesParticipant=2000;        MatrixMock mock=new MatrixMock(rows, cols,search);        Result result=new Result(rows);        Grouper grouper=new Grouper(result);        CyclicBarrier barrier=new CyclicBarrier(participants,grouper);        Searcher searchers[]=new Searcher[participants];        for (int i=0; i
一次运行结果:

Mock: There are 1001252 occurrence of 5 in generated data.

Main: The main thread has finished.
Thread-0: Processing lines from 0 to 2000.
Thread-4: Processing lines from 8000 to 10000.
Thread-1: Processing lines from 2000 to 4000.
Thread-3: Processing lines from 6000 to 8000.
Thread-2: Processing lines from 4000 to 6000.
Thread-1: Lines processed.
Thread-3: Lines processed.
Thread-2: Lines processed.
Thread-0: Lines processed.
Thread-4: Lines processed.
Grouper: Processing results...
Grouper: Total result: 1001252.

要点

1.CyclicBarrier还提供了getNumberWaiting()方法,用来获取当前被阻塞的线程个数;

2.利用该类执行分治任务是一个很不错的选择;

转载于:https://my.oschina.net/u/1387007/blog/343265

你可能感兴趣的文章
2015.5.21 VS2010中引用Word组件后提示 类型“Microsoft.Office.Interop.Word.ApplicationClass”未定义构造函数 解决方法...
查看>>
动态网页技术的发展
查看>>
17-python-主要内置函数
查看>>
19-python-迭代器、生成器
查看>>
用DataGridView导入TXT文件,并导出为XLS文件
查看>>
maven3常用命令、java项目搭建、web项目搭建
查看>>
1503. [NOI2004]郁闷的出纳员【平衡树-splay】
查看>>
Oracle 2
查看>>
vue js 判断鼠标滚动到底部 数据更新
查看>>
一个ios的各种组件、代码分类,供参考
查看>>
Shell脚本学习之sed详解
查看>>
bugDone
查看>>
Go:json(序列化、反序列化)
查看>>
Python 类的用法
查看>>
动态链接和静态链接的区别
查看>>
解决Python开发过程中依赖库打包问题的方法
查看>>
Git学习系列之命令大全(二)
查看>>
java基础(五)-----关键字static
查看>>
什么是PLI?
查看>>
[UIKit学习]04.关于HUD提示框,定时任务、开发关于资源常见问题
查看>>