java并發(fā)編程專題(九)----(JUC)淺析CyclicBarrier
上一篇我們介紹了CountDownlatch,我們知道CountDownlatch是“在完成一組正在其他線程中執(zhí)行的操作之前,它允許一個或多個線程一直等待”,即CountDownLatch的作用是允許1或N個線程等待其他線程完成執(zhí)行,而我們今天要介紹的CyclicBarrier則是允許N個線程相互等待。
1.CyclicBarrier簡介
CyclicBarrier 的字面意思是可循環(huán)使用(Cyclic)的屏障(Barrier)。它要做的事情是,讓一組線程到達一個屏障(也可以叫同步點)時被阻塞,直到最后一個線程到達屏障時,屏障才會開門,所有被屏障攔截的線程才會繼續(xù)干活。 在JDK中對CyclicBarrier是這樣說的“允許一組線程全部等待彼此到達公共屏障點的同步輔助。 循環(huán)障礙在涉及必須偶爾彼此等待的固定大小的線程程序中是有用的。屏障稱為循環(huán) ,因為它可以在等待線程釋放后重新使用”。CountDownLatch的計數(shù)器無法被重置;CyclicBarrier的計數(shù)器可以被重置后使用,因此它被稱為是循環(huán)的barrier。
我們先來看一下他的構(gòu)造方法和使用方式:
構(gòu)造函數(shù):
CyclicBarrier(int parties) //其參數(shù)表示屏障攔截的線程數(shù)量,每個線程調(diào)用await方法告
訴CyclicBarrier我已經(jīng)到達了屏障,然后當前線程被阻塞。CyclicBarrier (int parties, Runnable barrierAction) //創(chuàng)建一個新的CyclicBarrier ,
當給定數(shù)量的參與者(線程)等待它時,它將跳閘,當障礙跳閘時,它
將執(zhí)行 給定的障礙動作(Runnable參數(shù)提供),由最后一個線程進入障礙。
方法:
int await() //在所有參與者都已經(jīng)在此 barrier 上調(diào)用 await 方法之前,將一直等待。
方法之前將一直等待,或者超出了指定的等待時間。
int getNumberWaiting() //返回當前在屏障處等待的參與者數(shù)目。
int getParties() //返回要求啟動此 barrier 的參與者數(shù)目。
boolean isBroken() //查詢此屏障是否處于損壞狀態(tài)。
void reset() //將屏障重置為其初始狀態(tài)。
下面我們來看一個小程序了解一下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(Thread.currentThread().getName()+"正在等待...");
}
}).start();
try {
c.await();
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName()+"正在等待...");
System.out.println("人夠了,出發(fā)吧 當前有 "+c.getParties()+" 個人參與比賽");
}
}
輸出結(jié)果為:
Thread-0正在等待...
main正在等待...
人夠了,出發(fā)吧 當前有 2 個人參與比賽Process finished with exit code 0
在上面程序中如果我們把”static CyclicBarrier c = new CyclicBarrier(2);”中的參數(shù)2修改為3的話改程序中的線程Thread-0和main則會一直等待下去,因為CyclicBarrier是讓一組線程到達一個屏障(也可以叫同步點)時被阻塞,直到最后一個線程到達屏障時,屏障才會開門,而這最后一個線程遲遲不來,所以屏障也不會被打開。
CyclicBarrier還提供一個更高級的構(gòu)造函數(shù)CyclicBarrier(int parties, Runnable barrierAction),用于在線程到達屏障時,優(yōu)先執(zhí)行barrierAction,方便處理更復雜的業(yè)務場景。我們來看一下示例:
public class CyclicBarrierTest {
static CyclicBarrier c = new CyclicBarrier(2,new PrioExecut());
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
try {
c.await();
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName()+"正在等待...");
}
}).start();
try {
c.await();
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName()+"正在等待...");
System.out.println("人夠了,出發(fā)吧 當前有 "+c.getParties()+" 個人參與比賽");
}
}
class PrioExecut implements Runnable{
@Override
public void run() {
System.out.println("我會先跑5秒,不管你信不信!");
}
}
執(zhí)行結(jié)果為:
我會先跑5秒,不管你信不信!
Thread-0正在等待...
main正在等待...
人夠了,出發(fā)吧 當前有 2 個人參與比賽Process finished with exit code 0
我們可以看到構(gòu)造方法中的參數(shù):new PrioExecut()中的線程會優(yōu)先執(zhí)行。
2.CyclicBarrier的應用場景
CyclicBarrier可以用于多線程計算數(shù)據(jù),最后合并計算結(jié)果的應用場景。比如在支付業(yè)務中,我們可以按照事先劃分好的片區(qū)的形式來統(tǒng)計日收支流水,然后根據(jù)片區(qū)的計算結(jié)果,使用Runnable barrierAction來進行匯總這是一個很好的實現(xiàn)。
3.CyclicBarrier和CountDownLatch的區(qū)別
在javadoc里面的描述是這樣的:
CountDownLatch: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
CyclicBarrier : A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.
- 根據(jù)我的理解:對于CountDownLatch來說,重點是那個“一個線程”, 它在等待其余線程執(zhí)行完畢他才能執(zhí)行,而另外那N的線程在把“某個事情”做完之后可以繼續(xù)等待,可以終止。比如上文說的跑步的例子,只有5位跑步者同時準備好了,裁判才能下令開始跑步;CyclicBarrier強調(diào)的是n個線程,大家相互等待,只要有一個沒完成,所有人都得等著。
- CountDownLatch的計數(shù)器無法被重置;CyclicBarrier的計數(shù)器可以使用reset() 方法重置。所以CyclicBarrier能處理更為復雜的業(yè)務場景,比如如果計算發(fā)生錯誤,可以重置計數(shù)器,并讓線程們重新執(zhí)行一次。
以上就是java并發(fā)編程專題(九)----(JUC)淺析CyclicBarrier的詳細內(nèi)容,更多關于java juc CyclicBarrier的資料請關注腳本之家其它相關文章!
相關文章
java利用delayedQueue實現(xiàn)本地的延遲隊列
這篇文章主要給大家介紹了java利用delayedQueue實現(xiàn)本地的延遲隊列的相關資料,文中介紹的非常詳細,相信對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。2017-04-04
Java中struts2和spring MVC的區(qū)別_動力節(jié)點Java學院整理
這篇文章主要介紹了Java中struts2和spring MVC的區(qū)別,非常不錯,具有參考借鑒價值,需要的朋友參考下吧2017-09-09
springboot 在ftl頁面上使用shiro標簽的實例代碼
這篇文章主要介紹了springboot 在ftl頁面上使用shiro標簽的實例代碼,通過文字說明結(jié)合實例的形式給大家介紹的非常詳細,需要的朋友參考下吧2018-05-05

