Java多線程中的CyclicBarrier使用方法詳解
CyclicBarrier
特點(diǎn)
1、同步輔助類
2、同類相互等待(多線程間)
3、計(jì)數(shù)是加法操作
缺點(diǎn)
1、無法動(dòng)態(tài)添加parties計(jì)數(shù)
2、調(diào)用一次await()僅占用一個(gè)parties計(jì)數(shù)
簡(jiǎn)述與示例
一種同步輔助工具,它允許一組線程都等待對(duì)方到達(dá)公共障礙點(diǎn)。在涉及固定大小的線程的程序中,CyclicBarriers非常有用,這些線程間必須相互等待。
該屏障之所以稱為cyclic,是因?yàn)樗梢栽诘却木€程被釋放之后被重用。
CyclicBarrier支持一個(gè)可選的Runnable,該命令在每個(gè)障礙點(diǎn)運(yùn)行一次,在多線程中的最后一個(gè)線程到達(dá)之后,但在所有線程被釋放之前。
這個(gè)barrier操作對(duì)于在任何一方繼續(xù)之前更新共享狀態(tài)非常有用。
示例用法:下面是一個(gè)在并行分解設(shè)計(jì)中使用barrier的示例:
public class Solver { final int N; final float[][] data; final CyclicBarrier barrier; volatile boolean over = false; public Solver(float[][] matrix) throws InterruptedException { data = matrix; N = matrix.length; //每一輪循環(huán)都會(huì)執(zhí)行,并且需要run執(zhí)行完才會(huì)觸發(fā)下一輪開啟. Runnable barrierAction = new Runnable() { @Override public void run() { System.out.println("Solver.run"); over = true; } }; //初始化CyclicBarrier barrier = new CyclicBarrier(N, barrierAction); List<Thread> threads = new ArrayList<>(N); for (int i = 0; i < N; i++) { Thread thread = new Thread(new Worker(i)); threads.add(thread); thread.start(); } // wait until done for (Thread thread : threads) { thread.join(); } } //程序入口 public static void main(String[] args) throws InterruptedException { float[][] matrix = {{1.2F}, {2.2F}}; Solver solver = new Solver(matrix); } class Worker implements Runnable { int myRow; Worker(int row) { myRow = row; } @Override public void run() { while (!done()) { processRow(myRow); try { barrier.await(); } catch (InterruptedException | BrokenBarrierException ex) { return; } } } private void processRow(int myRow) { System.out.println("Worker.processRow:" + myRow); } private boolean done() { return over; } } }
在這里,每個(gè)工作線程處理矩陣中的一行,然后在barrier處等待,直到所有行都處理完畢。
處理完所有行后,將執(zhí)行提供的Runnable barrier操作并合并行。
如果合并確定找到了一個(gè)解決方案,那么done()將返回true,并且每個(gè)worker將終止。
如果barrier操作在執(zhí)行時(shí)不依賴于被掛起的參與者,那么參與者中的任何線程都可以在它被釋放時(shí)執(zhí)行該操作。
為了方便實(shí)現(xiàn)這一點(diǎn),每次調(diào)用await都會(huì)返回barrier處該線程的到達(dá)索引。
然后您可以選擇哪個(gè)線程應(yīng)該執(zhí)行barrier操作,例如:
if (barrier.await() == 0) { // log the completion of this iteration }
CyclicBarrier使用一個(gè)動(dòng)靜極限的破碎模型同步嘗試失敗:如果一個(gè)線程離開障礙點(diǎn)過早中斷,失敗,或超時(shí),所有其他線程等待障礙點(diǎn)也將離開異常通過BrokenBarrierException(或InterruptedException如果他們也被打斷了大約在同一時(shí)間)。
內(nèi)存一致性影響:在線程中調(diào)用await()之前的操作發(fā)生——在barrier操作之前發(fā)生——在其他線程中對(duì)應(yīng)的await()成功返回后的操作之前。
方法介紹
構(gòu)造方法
CyclicBarrier(int parties, Runnable barrierAction) //添加線程在屏障達(dá)到時(shí)觸發(fā)!線程會(huì)阻塞下一輪開始直到該線程執(zhí)行完畢。
普通方法
int getParties() //獲取當(dāng)前設(shè)置的屏障數(shù)
int await() //等待直到所有線程執(zhí)行await達(dá)到屏障數(shù)
int await(long timeout, TimeUnit unit) //等待直到所有線程執(zhí)行await達(dá)到屏障數(shù)或者超過指定超時(shí)時(shí)間
boolean isBroken() //查詢當(dāng)前屏障是否處于broken狀態(tài)
void reset() //重置當(dāng)前屏障數(shù)到初始時(shí)數(shù)量
int getNumberWaiting() //查詢當(dāng)前等待未到達(dá)屏障值的線程數(shù)
到此這篇關(guān)于Java多線程中的CyclicBarrier使用方法詳解的文章就介紹到這了,更多相關(guān)Java的CyclicBarrier內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis-Plus自動(dòng)化填充的踩坑記錄及解決
這篇文章主要介紹了MyBatis-Plus自動(dòng)化填充的踩坑記錄及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03Spring中的@ConditionalOnProperty注解詳解
這篇文章主要介紹了Spring中的@ConditionalOnProperty注解詳解,常見的@Conditionalxxx開頭的注解我們稱之為條件注解,常見的條件注解有,簡(jiǎn)單來講,一般是在配置類上或者是@Bean修飾的方法上,添加此注解表示一個(gè)類是否要被Spring上下文加載,需要的朋友可以參考下2024-01-01MyBatis中#{}?和?${}?的區(qū)別和動(dòng)態(tài)?SQL詳解
這篇文章主要介紹了MyBatis中#{}和${}的區(qū)別,包括參數(shù)傳遞、安全性、性能等方面,然后詳細(xì)介紹了如何使用#{}和${}進(jìn)行排序、模糊查詢、動(dòng)態(tài)SQL、數(shù)據(jù)庫連接池等操作,最后,總結(jié)了注解方式的動(dòng)態(tài)SQL,感興趣的朋友跟隨小編一起看看吧2024-11-11淺談java二進(jìn)制、十進(jìn)制、十六進(jìn)制、字符串之間的相互轉(zhuǎn)換
下面小編就為大家?guī)硪黄獪\談二進(jìn)制、十進(jìn)制、十六進(jìn)制、字符串之間的相互轉(zhuǎn)換。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考,一起跟隨小編過來看看吧2016-06-06IntelliJ IDEA遠(yuǎn)程Debug Linux的Java程序,找問題不要只會(huì)看日志了(推薦)
這篇文章主要介紹了IntelliJ IDEA遠(yuǎn)程Debug Linux的Java程序,找問題不要只會(huì)看日志了,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09詳解Spring Boot使用系統(tǒng)參數(shù)表提升系統(tǒng)的靈活性
Spring Boot項(xiàng)目中常有一些相對(duì)穩(wěn)定的參數(shù)設(shè)置項(xiàng),其作用范圍是系統(tǒng)級(jí)的或模塊級(jí)的,這些參數(shù)稱為系統(tǒng)參數(shù)。這些變量以參數(shù)形式進(jìn)行配置,從而提高變動(dòng)和擴(kuò)展的靈活性,保持代碼的穩(wěn)定性2021-06-06Java設(shè)計(jì)模式之23種設(shè)計(jì)模式詳解
這篇文章主要介紹了Java設(shè)計(jì)模式之23種設(shè)計(jì)模式詳解,設(shè)計(jì)模式使代碼編制真正工程化,設(shè)計(jì)模式是軟件工程的基石,項(xiàng)目中合理的運(yùn)用設(shè)計(jì)模式可以完美的解決很多問題,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07