网上查了几个例子,发现几乎都直接可以用CountDownLatch来替换,于是自己写了一个例子来说明CyclicBarrier的好处,jdk用的8。例子是用N个线程,每个线程分别同时开始填写第0列里面的N行数据,比如线程0填写0列0行并等待,线程1填写0列1行并等待。。。直到所有线程填写0列完成,再又开始同时填写第1列,直到填写完成。个人认为和CountDownLatch的最大区别在于,CyclicBarrier是可以重复使用的。
package concurrent;
import org.junit.Test;
import java.util.Random;
import java.util.concurrent.*;
/**
* 栅栏
*
* @author Dean
*/
public class TestCyclicBarrier {
private int N = 3; //线程数,也是行数
private int columnNum = 4;//列数
private int data[][] = new int[N][columnNum];
private int currentColumn = 0; //当前处理列
private CyclicBarrier cyclicBarrier;
private boolean done = false;
/**
* 模拟N个线程并发逐列填充二维数组并计算该列合计,例子模仿自CyclicBarrier JAVA API
*/
@Test
public void test() throws InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
//CyclicBarrier也有无参构造函数
cyclicBarrier = new CyclicBarrier(N, () -> {
int total = data[0][currentColumn] + data[1][currentColumn] + data[2][currentColumn];
System.out.println("第" + currentColumn + "列完成计算,合计=" + total);
currentColumn++;
//这里可以控制是否一直计算下去
if (currentColumn == columnNum) {
done = true;
}
});
for (int i = 0; i < N; i++) {
executorService.execute(new Worker(i));
}
while(!done){
TimeUnit.SECONDS.sleep(2);//主线程等待
}
System.out.println("打印二维数组");
for (int i = 0; i < N; i++) {
System.out.print("[");
for (int j = 0; j < columnNum; j++) {
System.out.print(data[i][j] + "-");
}
System.out.println("]");
}
}
private class Worker implements Runnable {
int myRow;
Worker(int row) {
myRow = row;
}
@Override
public void run() {
while (!done) {
try {
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
} catch (InterruptedException e) {
e.printStackTrace();
}
int num = new Random().nextInt(9);
System.out.println("当前列=" + currentColumn + ",当前行=" + myRow + ",数字=" + num);
data[myRow][currentColumn] = num;
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
}
控制台输出:
当前列=0,当前行=1,数字=2当前列=0,当前行=0,数字=2
当前列=0,当前行=2,数字=5
第0列完成计算,合计=9
当前列=1,当前行=1,数字=6
当前列=1,当前行=2,数字=3
当前列=1,当前行=0,数字=6
第1列完成计算,合计=15
当前列=2,当前行=0,数字=8
当前列=2,当前行=2,数字=0
当前列=2,当前行=1,数字=7
第2列完成计算,合计=15
当前列=3,当前行=0,数字=8
当前列=3,当前行=1,数字=6
当前列=3,当前行=2,数字=5
第3列完成计算,合计=19
打印二维数组
[2-6-8-8-]
[2-6-7-6-]
[5-3-0-5-]