CyclicBarrier使用示例
package com.company.cr;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import org.junit.jupiter.api.Test;
/**
* @author tangcheng
* @see java.util.concurrent.CyclicBarrier
*/
public class CyclicBarriersTests {
private int[][] data = new int[][]{
{5, 2, 4},
{3, 4, 0},
{10, 7, 1},
{1, 0, 8},
};
private volatile boolean done = false;
private CyclicBarrier barrier
= new CyclicBarrier(data.length, new Runnable() {
@Override
public void run() {
int total;
if (Math.abs((total = calculate(data))) > 500) {
done = true;
}
System.out.println(String.format("current result=%s, tripping thread=%s"
, total, Thread.currentThread().getName()));
}
});
@Test
public void go_Tests() throws InterruptedException {
int num = data.length;
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < num; i++) {
threads.add(
new Thread(new Worker(i), String.format("Thread For Number [%s]", i))
);
}
// start all threads
for (Thread t : threads) {
t.start();
}
/*
// 线程中断
Thread.sleep(6000);
threads.get(2).interrupt();
*/
// prevent main thread from exiting
for (Thread t : threads) {
t.join();
}
System.out.println("barrier broken ? " + barrier.isBroken());
System.out.println("==== END ====");
}
private class Worker implements Runnable {
final int myRow;
public boolean isEven() {
return myRow / 2 == 0;
}
Worker(int myRow) {
this.myRow = myRow;
}
@Override
public void run() {
while (!done) {
// [0,1) -> [0,1000) -> [100, 1100)
long waitTime = Double.valueOf(Math.random() * 1000 + 100).longValue();
int[] arr = data[myRow];
for (int idx = 0; idx < arr.length; idx++) {
int old = arr[idx];
// [0,1) -> [0,10) -> [1,11)
int random = Double.valueOf(Math.random() * 10 + 1).intValue() * (isEven() ? 1 : -1);
arr[idx] = old + random;
try {
Thread.sleep(waitTime);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println(String.format("thread interrupt(inner loop) => %s "
, Thread.currentThread().getName()));
break;
}
}
System.out.println(String.format("row=%s, arr=%s", myRow, Arrays.toString(arr)));
try {
int reach = barrier.await();
System.out.println(String.format("thread=%s, row=%s, reach=%s, trip=%s"
, Thread.currentThread().getName(), myRow, reach, reach == 0));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println(String.format("thread interrupt(outer loop) => %s "
, Thread.currentThread().getName()));
break;
} catch (BrokenBarrierException e) {
System.out.println(String.format("BrokenBarrierException => %s "
, Thread.currentThread().getName()));
break;
}
}
}
}
private int calculate(int[][] data) {
int total = 0;
for (int[] datum : data) {
for (int i : datum) {
total = total + i;
}
}
return total;
}
}
// created at 2022/6/11 17:40