1. 程式人生 > >同步工具類-----循環柵欄:CyclicBarrier

同步工具類-----循環柵欄:CyclicBarrier

override bool oid 當前 cli tro name this ==

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

public class TestCyclicBarrier {
public static class Soldier implements Runnable { private String soldier; private final CyclicBarrier cyclicBarrier;
private long timeout; public Soldier(CyclicBarrier cyclicBarrier, String soldier, long timeout) { this.cyclicBarrier = cyclicBarrier; this.timeout = timeout; this.soldier = soldier; } @Override public void run() {
try { // 等待所有士兵到齊 cyclicBarrier.await(); doWork(); // 等待所有士兵完成工作 cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }
void doWork() { try { // Thread.sleep(Math.abs(new Random().nextInt() % 100000)); Thread.sleep(timeout); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(soldier + ":任務完成!【用時: " + timeout / 1000 + " 秒】, " + "當前線程:" + Thread.currentThread().getName()); } } public static class BarrierRun implements Runnable { boolean flag; int N; private BarrierRun(boolean flag, int n) { this.flag = flag; N = n; } @Override public void run() { if (flag) { System.err.println("司令:【士兵" + N + "個,任務完成!】," + "【當前執行線程:" + Thread.currentThread().getName() + "】"); } else { System.err.println("司令:【士兵" + N + "個,集合完畢!】," + "【當前執行線程:" + Thread.currentThread().getName() + "】"); flag = true; } } } public static void main(String[] args) throws InterruptedException { final int N = 10; Thread[] soldierThreads = new Thread[N]; boolean flag = false;
     // CyclicBarrier 可以接收一個Runnable類型參數作為barrierAction
// 所謂barrierAction就是當計數器一次計數完成(成功通過柵欄)後的柵欄操作,系統會在一個子任務線程中)執行的動作,但在阻塞線程被釋放前是不能執行的
// 如果所有線程都成功地通過了柵欄,那麽await將為每個線程返回一個唯一的到達索引號,我們可以利用這些索引來“選舉”產生一個領導線程,並在下一次叠代中由該領導線程執行一些特殊的工作。
CyclicBarrier cyclicBarrier
= new CyclicBarrier(N, new BarrierRun(flag, N)); System.err.println("集合隊伍!"); TimeUnit.SECONDS.sleep(1); String tname; for (int i = 0; i < N; ++i) { System.out.println("士兵" + i + "報道!"); long timeout = (int) (1 + Math.random() * 10) * 1000; tname = "士兵" + i; soldierThreads[i] = new Thread(new Soldier(cyclicBarrier, tname, timeout), tname); // soldierThreads[i].setName(tname); soldierThreads[i].start(); /*if( i == 5){ soldierThreads[i].interrupt(); }*/ } } }

執行結果:

  1. 可見兩次BarrierRun 任務分別是在 兩個子任務線程中執行的。

技術分享圖片

同步工具類-----循環柵欄:CyclicBarrier