CyclicBarrierをについて
CyclicBarrierをデフォルトコンストラクタがCyclicBarrierを(int型のパーティー)で、そのパラメータがインターセプトにスレッド障壁の数を示し、各スレッドがのawaitメソッドを呼び出しCyclicBarrierを、私は、現在のスレッドがブロックされ、バリアに達しているように指示します。
public class CyclicBarrierTest {
static CyclicBarrier c = new CyclicBarrier(2);
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
try {
c.await();
} catch (Exception e) {
}
System.out.println(1);
}
}).start();
try {
c.await();
} catch (Exception e) {
}
System.out.println(2);
}
}
メインスレッドと子スレッドのスケジューリングはCPUによって決定されるべき、2つのスレッドが実行する可能性があり、それは、2つの出力を生成します
1
2
2
1
それは、2つのバリアに到達する前に、新しいCyclicBarrierを(2)新しいCyclicBarrierを(3)に変更された場合に何の第三のスレッドのawait実行方法がないため、メインスレッドとサブスレッドは、永久に待機する、即ち何第三のスレッドは、バリアに到達していませんスレッドは実行されません
CyclicBarrierをもCyclicBarrierを(int型のパーティー、RunnableをbarrierAction)より高度なコンストラクタを提供しては
優先的に、より複雑なビジネスシナリオを扱いやすいbarrierActionを、実行時にバリア到着郡、使用されています。
public class CyclicBarrierTest2 {
static CyclicBarrier c = new CyclicBarrier(2, new A()); 设置拦截线程的数量是2,所以必须等代码中的第一个线程和线程A都执行完之后,才会执行主线程。
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
try {
c.await();
} catch (Exception e) {
}
System.out.println(1);
}
}).start();
try {
c.await();
} catch (Exception e) {
}
System.out.println(2);
}
static class A implements Runnable {
@Override
public void run() {
System.out.println(3);
}
}
}
CyclicBarrierをシナリオ
CyclicBarrierを、マルチスレッドコンピューティング、データ、最後のシーンの組み合わされた結果のために使用することができます。
たとえば、Excelを持つユーザーは、マルチスレッドの水の使用中の各シートを処理するために、最初のバンクを年近くの銀行水につき1つのアカウントのセーブシートあたりのすべての銀行の水を節約し、現在のユーザーの日々の水バンクをカウントする必要があります両方の平均毎日銀行水の各シートを与えるために行った後、最終的に、これらのスレッドの結果とbarrierAction、全体Excelは平均毎日銀行水を計算
银行流水处理服务类
public class BankWaterService implements Runnable {
创建4个屏障,处理完之后执行当前类的run方法
private CyclicBarrier c = new CyclicBarrier(4, this);
假设只有4个sheet,所以只启动4个线程 ,使用线程池创建4个线程
private Executor executor = Executors.newFixedThreadPool(4);
保存每个sheet计算出的银流结果
private ConcurrentHashMap<String, Integer> sheetBankWaterCount = new ConcurrentHashMap<String, Integer>();
private void count() {
for (int i = 0; i < 4; i++) {
executor.execute(new Runnable() {
@Override
public void run() { 计算当前sheet的银流数据,计算代码省略
sheetBankWaterCount.put(Thread.currentThread().getName(), 1); 银流计算完成,插入一个屏障
try {
c.await();
} catch (InterruptedException |
BrokenBarrierException e) {
e.printStackTrace();
}
}
});
}
}
@Override
public void run() {
int result = 0; 汇总每个sheet计算出的结果
for (Map.Entry<String, Integer> sheet : sheetBankWaterCount.entrySet()) {
result += sheet.getValue();
} 将结果输出
sheetBankWaterCount.put("result", result);
System.out.println(result);
}
public static void main(String[] args) {
BankWaterService bankWaterCount = new BankWaterService();
bankWaterCount.count();
}
}
CyclicBarrierを差分たCountDownLatch
たCountDownLatchは、カウンタ一度だけ使用され、そしてリセットするCyclicBarrierをカウンタリセット()メソッドを使用してもよいです。
だから、CyclicBarrierを、より複雑なビジネスシナリオを処理することができます。計算エラーが発生した場合たとえば、あなたはカウンタをリセットすることができますし、もう一度最初からスレッドをしましょう。
CyclicBarrierをも、そのようなCyclicBarrierをがブロックされたスレッドの数を取得するためにはgetNumber待機の方法として他の有用な方法を提供します。isBroken()メソッドはブロックされたスレッドが中断されたかどうかを調べるために使用されます。
public class CyclicBarrierTest3 {
static CyclicBarrier c = new CyclicBarrier(2);
public static void main(String[] args) throws InterruptedException,BrokenBarrierException
{
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
c.await();
} catch (Exception e) {
}
}
});
thread.start();
thread.interrupt();
try {
c.await();
} catch (Exception e) {
System.out.println(c.isBroken());
}
}
}
真の出力