java.util.concurrent.CyclicBarrier提供了一种多阶段协同器的工具,每个阶段都等待固定数目的线程(parties)到达阻塞点(cyclicBarrier.await()),然后执行cyclicBarrier.barrierCommand.run(),并唤醒所有参与者的阻塞状态,进入下一个阶段。为了更好的理解该工具类的使用场景,下面的代码改造自JDK API的示例,目的是多线程读取矩阵的列信息并按序输出。
public class TestBarrier {
public static void main(String[] args) throws InterruptedException {
int[][] matrix = { {1, 2, 3},
{3, 4, 5},
{5, 6, 7},
{7, 8, 9} };
new TestBarrier(matrix);
}
final int[][] data;
final CyclicBarrier barrier;
int[] curColData;
public TestBarrier(int[][] matrix) throws InterruptedException {
this.data = matrix;
final int N = matrix.length;
this.curColData = new int[N];
Runnable barrierAction = new Runnable() {
public void run() {
System.out.println(Thread.currentThread() + "\n" + Arrays.toString(curColData));
}
};
barrier = new CyclicBarrier(N, barrierAction);
List<Thread> threads = new ArrayList<Thread>(N);
for (int i = 0; i < N; i++) {
Thread thread = new Thread(new Worker(i, matrix));
threads.add(thread);
thread.start();
}
// wait until done
for (Thread thread : threads)
thread.join();
System.out.println(Thread.currentThread() + ": Good Job!");
}
class Worker implements Runnable {
int myRow;
int[] rowData;
int index = 0;
Worker(int row, int[][] matrix) {
myRow = row;
this.rowData = matrix[row];
}
public void run() {
while (index < rowData.length) {// !done()) {
TestBarrier.this.curColData[myRow] = rowData[index++];
try {
barrier.await();
System.out.println(Thread.currentThread() + "go");
} catch (InterruptedException ex) {
return;
} catch (BrokenBarrierException ex) {
return;
}
}
}
}
}
输出结果如下:
Thread[Thread-3,5,main]
[1, 3, 5, 7]
Thread[Thread-0,5,main]go
Thread[Thread-2,5,main]go
Thread[Thread-1,5,main]go
Thread[Thread-3,5,main]go
Thread[Thread-3,5,main]
[2, 4, 6, 8]
Thread[Thread-3,5,main]go
Thread[Thread-0,5,main]go
Thread[Thread-1,5,main]go
Thread[Thread-2,5,main]go
Thread[Thread-2,5,main]
[3, 5, 7, 9]
Thread[Thread-2,5,main]go
Thread[Thread-0,5,main]go
Thread[Thread-1,5,main]go
Thread[Thread-3,5,main]go
Thread[main,5,main]: Good Job!