摘要:考慮大量線程運(yùn)行在一次計(jì)算的不同部分的情形。一旦所有的線程都到達(dá)了這個(gè)柵欄,柵欄就撤銷(xiāo),線程可以繼續(xù)運(yùn)行。那些已經(jīng)在等待的線程立即中止的調(diào)用。如果在執(zhí)行屏障操作過(guò)程中發(fā)生異常,則該異常將傳播到當(dāng)前線程中,并將置于損壞狀態(tài)。
【同步器
java.util.concurrent包包含幾個(gè)能幫助人們管理相互合作的線程集的類(lèi)。這些機(jī)制具有為線程直間的共用集結(jié)點(diǎn)模式提供的‘預(yù)制功能’。如果有一個(gè)相互合作的線程滿足這些行為模式之一,那么應(yīng)該直接使用提供的類(lèi)庫(kù)而不是顯示的使用鎖與條件的集合。
【柵欄CyclicBarrier類(lèi)實(shí)現(xiàn)了一個(gè)集結(jié)點(diǎn)(rendezvous)稱(chēng)為柵欄(barrier)??紤]大量線程運(yùn)行在一次計(jì)算的不同部分的情形。當(dāng)所有部分都準(zhǔn)備好時(shí),需要把結(jié)果組合到一起。當(dāng)一個(gè)線程完成了它那部分的任務(wù)后,我們讓他運(yùn)行到柵欄處。一旦所有的線程都到達(dá)了這個(gè)柵欄,柵欄就撤銷(xiāo),線程可以繼續(xù)運(yùn)行。如果任何一個(gè)線程在柵欄上等待時(shí)離開(kāi),那么柵欄就被破壞掉(線程離開(kāi)可能時(shí)等待超時(shí))。這種情況下,其他所有線程await方法上拋出BrokenBarrierException異常。那些已經(jīng)在等待的線程立即中止await的調(diào)用。可以提供一個(gè)可選的柵欄動(dòng)作,當(dāng)所有線程到達(dá)柵欄時(shí),就會(huì)執(zhí)行這個(gè)動(dòng)作。
Runnable barrierAction = ... CyclicBarrier barrire = new CyclicBarrier(nthreads,barrierAction);
柵欄被稱(chēng)為時(shí)循環(huán)的,以為可以在所有等待的線程被釋放后重用(這里與倒計(jì)時(shí)門(mén)閂不同,倒計(jì)時(shí)門(mén)閂只能使用一次)。
【常用方法
public int await() throws InterruptedException,BrokenBarrierException:
在所有參與者都已經(jīng)在此 barrier 上調(diào)用 await方法之前,將一直等待。如果當(dāng)前線程不是將到達(dá)的最后一個(gè)線程,出于調(diào)度目的,將禁用它,且在發(fā)生以下情況之一前,該線程將一直處于休眠狀態(tài):
- 最后一個(gè)線程到達(dá);或者 - 其他某個(gè)線程中斷當(dāng)前線程;或者 - 其他某個(gè)線程中斷另一個(gè)等待線程;或者 - 其他某個(gè)線程在等待 barrier 時(shí)超時(shí);或者 - 其他某個(gè)線程在此 barrier 上調(diào)用 reset()。
如果當(dāng)前線程在進(jìn)入此方法時(shí)已經(jīng)設(shè)置了該線程的中斷狀態(tài);或者在等待時(shí)被中斷則InterruptedException,并且清除當(dāng)前線程的已中斷狀態(tài)。
如果在線程處于等待狀態(tài)時(shí) barrier 被 reset(),或者在調(diào)用 await 時(shí) barrier 被損壞,抑或任意一個(gè)線程正處于等待狀態(tài),則拋出 BrokenBarrierException 異常。
如果任何線程在等待時(shí)被 中斷,則其他所有等待線程都將拋出 BrokenBarrierException 異常,并將 barrier 置于損壞狀態(tài)。
如果當(dāng)前線程是最后一個(gè)將要到達(dá)的線程,并且構(gòu)造方法中提供了一個(gè)非空的屏障操作,則在允許其他線程繼續(xù)運(yùn)行之前,當(dāng)前線程將運(yùn)行該操作。
如果在執(zhí)行屏障操作過(guò)程中發(fā)生異常,則該異常將傳播到當(dāng)前線程中,并將 barrier 置于損壞狀態(tài)。
返回:到達(dá)的當(dāng)前線程的索引,其中,索引 getParties() - 1 指示將到達(dá)的第一個(gè)線程,零指示最后一個(gè)到達(dá)的線程.
拋出:
InterruptedException - 如果當(dāng)前線程在等待時(shí)被中斷
BrokenBarrierException - 如果另一個(gè) 線程在當(dāng)前線程等待時(shí)被中斷或超時(shí),或者重置了 barrier,或者在調(diào)用 await 時(shí) barrier 被損壞,抑或由于異常而導(dǎo)致屏障操作(如果存在)失敗。
【例子1.應(yīng)用程序啟動(dòng)前,所有子線程準(zhǔn)備工作完成,不需要返回值
public class Application{ public static void main(String[] args) throws IOException, InterruptedException { //需要三個(gè)子線程準(zhǔn)備 CyclicBarrier barrier = new CyclicBarrier(3); //如果初始化barrier的線程數(shù),與實(shí)際子線程數(shù)不同,barrier將會(huì)一直等待 ExecutorService executor = Executors.newFixedThreadPool(3); executor.submit(new Thread(new InitThread(barrier, "子線程1"))); executor.submit(new Thread(new InitThread(barrier, "子線程2"))); executor.submit(new Thread(new InitThread(barrier, "子線程3"))); executor.shutdown(); } } class InitThread implements Runnable { // 一個(gè)同步輔助類(lèi),它允許一組線程互相等待,直到到達(dá)某個(gè)公共屏障點(diǎn) (common barrier point) private CyclicBarrier barrier; private String name; public InitThread(CyclicBarrier barrier, String name) { this.barrier = barrier; this.name = name; } @Override public void run() { try { Thread.sleep(1000 * (new Random()).nextInt(8)); System.out.println(name + " 初始化完成..."); barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } System.out.println(name + " 開(kāi)始運(yùn)行!"); } }
2.應(yīng)用程序啟動(dòng)前,所有子線程準(zhǔn)備工作完成,需要返回值匯總
public class ApplicationNeedReturn { public static void main(String[] args) throws IOException, InterruptedException, ExecutionException { //需要三個(gè)子線程準(zhǔn)備 CyclicBarrier barrier = new CyclicBarrier(3); //如果初始化barrier的線程數(shù),與實(shí)際子線程數(shù)不同,barrier將會(huì)一直等待 ExecutorService executor = Executors.newFixedThreadPool(3); FutureTasktime1 = new FutureTask (new InitThread2(barrier, "子線程1")); FutureTask time2 = new FutureTask (new InitThread2(barrier, "子線程2")); FutureTask time3 = new FutureTask (new InitThread2(barrier, "子線程3")); executor.submit(time1); executor.submit(time2); executor.submit(time3); long total = time1.get() + time2.get() + time3.get(); System.out.println("準(zhǔn)備完成,耗時(shí):" + total); executor.shutdown(); } } class InitThread2 implements Callable { private CyclicBarrier barrier; private String name; public InitThread2(CyclicBarrier barrier, String name) { this.barrier = barrier; this.name = name; } @Override public Long call() { long time = 1000 * (new Random()).nextInt(8); try { Thread.sleep(time); System.out.println(name + " 初始化完成... : " + time) ; barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } return time; } }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/68089.html
摘要:整個(gè)包,按照功能可以大致劃分如下鎖框架原子類(lèi)框架同步器框架集合框架執(zhí)行器框架本系列將按上述順序分析,分析所基于的源碼為。后,根據(jù)一系列常見(jiàn)的多線程設(shè)計(jì)模式,設(shè)計(jì)了并發(fā)包,其中包下提供了一系列基礎(chǔ)的鎖工具,用以對(duì)等進(jìn)行補(bǔ)充增強(qiáng)。 showImg(https://segmentfault.com/img/remote/1460000016012623); 本文首發(fā)于一世流云專(zhuān)欄:https...
摘要:本文探討并發(fā)中的其它問(wèn)題線程安全可見(jiàn)性活躍性等等。當(dāng)閉鎖到達(dá)結(jié)束狀態(tài)時(shí),門(mén)打開(kāi)并允許所有線程通過(guò)。在從返回時(shí)被叫醒時(shí),線程被放入鎖池,與其他線程競(jìng)爭(zhēng)重新獲得鎖。 本文探討Java并發(fā)中的其它問(wèn)題:線程安全、可見(jiàn)性、活躍性等等。 在行文之前,我想先推薦以下兩份資料,質(zhì)量很高:極客學(xué)院-Java并發(fā)編程讀書(shū)筆記-《Java并發(fā)編程實(shí)戰(zhàn)》 線程安全 《Java并發(fā)編程實(shí)戰(zhàn)》中提到了太多的術(shù)語(yǔ)...
摘要:今天給大家總結(jié)一下,面試中出鏡率很高的幾個(gè)多線程面試題,希望對(duì)大家學(xué)習(xí)和面試都能有所幫助。指令重排在單線程環(huán)境下不會(huì)出先問(wèn)題,但是在多線程環(huán)境下會(huì)導(dǎo)致一個(gè)線程獲得還沒(méi)有初始化的實(shí)例。使用可以禁止的指令重排,保證在多線程環(huán)境下也能正常運(yùn)行。 下面最近發(fā)的一些并發(fā)編程的文章匯總,通過(guò)閱讀這些文章大家再看大廠面試中的并發(fā)編程問(wèn)題就沒(méi)有那么頭疼了。今天給大家總結(jié)一下,面試中出鏡率很高的幾個(gè)多線...
摘要:分層支持分層一種樹(shù)形結(jié)構(gòu),通過(guò)構(gòu)造函數(shù)可以指定當(dāng)前待構(gòu)造的對(duì)象的父結(jié)點(diǎn)。當(dāng)一個(gè)的參與者數(shù)量變成時(shí),如果有該有父結(jié)點(diǎn),就會(huì)將它從父結(jié)點(diǎn)中溢移除。當(dāng)首次將某個(gè)結(jié)點(diǎn)鏈接到樹(shù)中時(shí),會(huì)同時(shí)向該結(jié)點(diǎn)的父結(jié)點(diǎn)注冊(cè)一個(gè)參與者。 showImg(https://segmentfault.com/img/remote/1460000016010947); 本文首發(fā)于一世流云專(zhuān)欄:https://segme...
摘要:的線程機(jī)制是搶占式。會(huì)讓出當(dāng)多個(gè)線程并發(fā)的對(duì)主存中的數(shù)據(jù)進(jìn)行操作時(shí),有且只有一個(gè)會(huì)成功,其余均失敗。和對(duì)象只有在困難的多線程問(wèn)題中才是必須的。 并發(fā)簡(jiǎn)述 并發(fā)通常是用于提高運(yùn)行在單處理器上的程序的性能。在單 CPU 機(jī)器上使用多任務(wù)的程序在任意時(shí)刻只在執(zhí)行一項(xiàng)工作。 并發(fā)編程使得一個(gè)程序可以被劃分為多個(gè)分離的、獨(dú)立的任務(wù)。一個(gè)線程就是在進(jìn)程中的一個(gè)單一的順序控制流。java的線程機(jī)制是...
閱讀 2767·2023-04-26 00:07
閱讀 2498·2021-11-15 11:37
閱讀 719·2021-10-19 11:44
閱讀 2241·2021-09-22 15:56
閱讀 1828·2021-09-10 10:50
閱讀 1572·2021-08-18 10:21
閱讀 2669·2019-08-30 15:53
閱讀 1695·2019-08-30 11:11