標籤:
繼續並發專題~
這次介紹CyclicBarrier:看一眼API的凝視:
/** * A synchronization aid that allows a set of threads to all wait for * each other to reach a common barrier point. CyclicBarriers are * useful in programs involving a fixed sized party of threads that * must occasionally wait for each other. The barrier is called * <em>cyclic</em> because it can be re-used after the waiting threads * are released.
大概意思:一個讓一組線程同一時候堵塞到一個位置的同步輔助類。在包括固定線程且線程間必須相互等待的情境中很實用。cyclic的意思是CyclicBarrier當等待的線程所有釋放之後,能夠反覆使用。
(英語水平就這樣了。。
。。)
CyclicBarrier 類似一個閘門,指定數目的線程都必須到達這個閘門,閘門才會開啟。
以下使用CyclicBarrier類比一個門禁系統:
需求是這種:到放學時間,全部的學生必須刷卡。然後人數齊了自己主動開門,統一回家。這個需求剛剛的,避免了把部分孩子丟在學校發生危急。特別是幼兒園或者小學生~~
package com.zhy.concurrency.cyclic;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;/** * 安全的門禁系統 * * @author zhy * */public class CyclicBarrierTest{/** * 學生總數 */private final int STUDENT_COUNT = 10;/** * 當人到齊。自己主動開門程式 */final CyclicBarrier barrier = new CyclicBarrier(STUDENT_COUNT,new Runnable(){@Overridepublic void run(){System.out.println("人到齊了。開門....");}});public void goHome() throws InterruptedException, BrokenBarrierException{System.out.println(Thread.currentThread().getName() + "已刷卡。等待開門回家~");barrier.await();System.out.println(Thread.currentThread().getName() + "放學回家~");}public static void main(String[] args) throws InterruptedException,BrokenBarrierException{final CyclicBarrierTest instance = new CyclicBarrierTest();/** * 每一個線程代表一個學生 */for (int i = 0; i < instance.STUDENT_COUNT; i++){new Thread("學生" + i +" " ){public void run(){try{instance.goHome();} catch (InterruptedException e){e.printStackTrace();} catch (BrokenBarrierException e){e.printStackTrace();}};}.start();}}}
輸出結果:
學生1 已刷卡,等待開門回家~學生3 已刷卡,等待開門回家~學生5 已刷卡,等待開門回家~學生9 已刷卡,等待開門回家~學生7 已刷卡,等待開門回家~學生0 已刷卡,等待開門回家~學生2 已刷卡。等待開門回家~學生6 已刷卡。等待開門回家~學生8 已刷卡。等待開門回家~學生4 已刷卡,等待開門回家~人到齊了,開門....學生4 放學回家~學生1 放學回家~學生3 放學回家~學生5 放學回家~學生9 放學回家~學生2 放學回家~學生6 放學回家~學生0 放學回家~學生7 放學回家~學生8 放學回家~
哈哈,假設哪個幼兒園用了這麼一套系統,孩子應該不會丟學校了吧。,,。開玩笑了;;
CyclicBarrier把全部的線程都堵塞在一個閥門位置,然後等到等待的線程數到達預設的值。就開啟這個閥門。記得是堵塞線程,不是堵塞操作,在同一個線程使勁掉await是沒什麼效果的。
上面的範例顯示了CyclicBarrier的基本使用方法。可是cyclic的功能並沒有顯示出來,既然凝視中講了,我們有必要來個範例看看:
我們改造下我們的門禁,畢竟刷卡好不現實,如今需求是這種:學生一個人走太危急,如今門衛放學在門口守著。讓學生3個一組的走。
package com.zhy.concurrency.cyclic;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;/** * 改造後的門禁系統 * * @author zhy * */public class CyclicBarrierTest2{/** * 學生總數 */private final int STUDENT_COUNT = 12;/** * 每3個人一組出門 */final CyclicBarrier barrier = new CyclicBarrier(3,new Runnable(){@Overridepublic void run(){System.out.println("有3個學生到齊了,允許存取....");}});public void goHome() throws InterruptedException, BrokenBarrierException{System.out.println(Thread.currentThread().getName() + "已刷卡。等待開門回家~");barrier.await();}public static void main(String[] args) throws InterruptedException,BrokenBarrierException{final CyclicBarrierTest2 instance = new CyclicBarrierTest2();/** * 每一個線程代表一個學生 */for (int i = 0; i < instance.STUDENT_COUNT; i++){new Thread("學生" + i +" " ){public void run(){try{instance.goHome();} catch (InterruptedException e){e.printStackTrace();} catch (BrokenBarrierException e){e.printStackTrace();}};}.start();}}}輸出結果:
學生0 已刷卡,等待開門回家~學生1 已刷卡。等待開門回家~學生2 已刷卡。等待開門回家~有3個學生到齊了,允許存取....學生3 已刷卡。等待開門回家~學生5 已刷卡,等待開門回家~學生7 已刷卡,等待開門回家~有3個學生到齊了。允許存取....學生4 已刷卡,等待開門回家~學生9 已刷卡,等待開門回家~學生6 已刷卡。等待開門回家~有3個學生到齊了,允許存取....學生11 已刷卡,等待開門回家~學生10 已刷卡,等待開門回家~學生8 已刷卡,等待開門回家~有3個學生到齊了,允許存取....
這個範例充分的體現了CyclicBarrier的複用性,是吧,這種系統也許更實在些,0成本~哈哈~。
好了,有興趣的歡迎留言、
Java 並發專題 : CyclicBarrier 打造一個安全的門禁系統