摘要:也是一個同步輔助類,它允許一組線程相互等待直到到達某個工作屏障點,通過他可以完成多線程之間的相互等待。每個線程都就緒之后才能執行后面的操作。是可重用的計數器,的使用場景和的使用場景很相似,可以用于多線程計算數據最后總計結果。
CyclicBarrier
CyclicBarrier也是一個同步輔助類,它允許一組線程相互等待直到到達某個工作屏障點,通過他可以完成多線程之間的相互等待。每個線程都就緒之后才能執行后面的操作。和CountLatch有相似的地方都是通過計數器來實現的。當某個線程執行了await()方法后就進入等待狀態,計數器進行加1操作,當增加后的值達到我們設定的值后,線程被喚醒,繼續執行后續操作。CyclicBarrier是可重用的計數器,CyclicBarrier的使用場景和CountDownLatch的使用場景很相似,可以用于多線程計算數據最后總計結果。
CyclicBarrier和CountDownLatch的使用區別:
CountDownLatch的計數器只能使用一次,CyclicBarrier可以用reset方法重置。
CountDownLatch是一個線程等待其他線程完成某個操作后才能繼續執行。也就是一個或個多線程等待其他的關系,而CyclicBarrier是實現了多個線程之間的相互等待,所有線程都滿足了條件之后才能繼續使用。
演示代碼
@Slf4j public class CyclicBarrierExample1 { private static CyclicBarrier barrier = new CyclicBarrier(5); public static void main(String[] args) throws Exception { ExecutorService executor = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { final int threadNum = i; Thread.sleep(1000); executor.execute(() -> { try { race(threadNum); } catch (Exception e) { log.error("exception", e); } }); } executor.shutdown(); } private static void race(int threadNum) throws Exception { Thread.sleep(1000); log.info("{} is ready", threadNum); barrier.await(); log.info("{} continue", threadNum); } }
輸出結果如下:
20:43:46.324 [pool-1-thread-1] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 0 is ready 20:43:47.322 [pool-1-thread-2] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 1 is ready 20:43:48.323 [pool-1-thread-3] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 2 is ready 20:43:49.323 [pool-1-thread-4] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 3 is ready 20:43:50.325 [pool-1-thread-5] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 4 is ready 20:43:50.325 [pool-1-thread-5] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 4 continue 20:43:50.325 [pool-1-thread-1] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 0 continue 20:43:50.325 [pool-1-thread-2] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 1 continue 20:43:50.325 [pool-1-thread-4] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 3 continue 20:43:50.325 [pool-1-thread-3] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 2 continue 20:43:51.325 [pool-1-thread-6] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 5 is ready 20:43:52.326 [pool-1-thread-1] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 6 is ready 20:43:53.326 [pool-1-thread-2] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 7 is ready 20:43:54.326 [pool-1-thread-4] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 8 is ready 20:43:55.327 [pool-1-thread-3] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 9 is ready 20:43:55.327 [pool-1-thread-3] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 9 continue 20:43:55.327 [pool-1-thread-6] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 5 continue 20:43:55.327 [pool-1-thread-1] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 6 continue 20:43:55.327 [pool-1-thread-2] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 7 continue 20:43:55.327 [pool-1-thread-4] INFO com.concurrency.example.aqs.CyclicBarrierExample1 - 8 continue
我們定義了 private static CyclicBarrier barrier = new CyclicBarrier(5),每次調用await后加1 知道等于5就一起執行接下來的操作。
我們在創建CyclicBarrier的時候是可以傳入一段runable的,下面看一下代碼
@Slf4j public class CyclicBarrierExample3 { private static CyclicBarrier barrier = new CyclicBarrier(5, () -> { log.info("callback is running"); }); public static void main(String[] args) throws Exception { ExecutorService executor = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { final int threadNum = i; Thread.sleep(1000); executor.execute(() -> { try { race(threadNum); } catch (Exception e) { log.error("exception", e); } }); } executor.shutdown(); } private static void race(int threadNum) throws Exception { Thread.sleep(1000); log.info("{} is ready", threadNum); barrier.await(); log.info("{} continue", threadNum); } }
在線程到達=執行屏障時,線程會優先執行這個runable
private static CyclicBarrier barrier = new CyclicBarrier(5, () -> { log.info("callback is running"); });
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/77687.html
摘要:在創建對象時,需要轉入一個值,用于初始化的成員變量,該成員變量表示屏障攔截的線程數。當到達屏障的線程數小于時,這些線程都會被阻塞住。當所有線程到達屏障后,將會被更新,表示進入新一輪的運行輪次中。 1.簡介 在分析完AbstractQueuedSynchronizer(以下簡稱 AQS)和ReentrantLock的原理后,本文將分析 java.util.concurrent 包下的兩個...
摘要:今天給大家總結一下,面試中出鏡率很高的幾個多線程面試題,希望對大家學習和面試都能有所幫助。指令重排在單線程環境下不會出先問題,但是在多線程環境下會導致一個線程獲得還沒有初始化的實例。使用可以禁止的指令重排,保證在多線程環境下也能正常運行。 下面最近發的一些并發編程的文章匯總,通過閱讀這些文章大家再看大廠面試中的并發編程問題就沒有那么頭疼了。今天給大家總結一下,面試中出鏡率很高的幾個多線...
摘要:當計數器值到達時,它表示所有的線程已經完成了任務,然后在閉鎖上等待的線程就可以恢復執行任務。這個類使用線程在達到某個條件后繼續執行的情況。 CountDownLatch CountDownLatch是在java1.5被引入的,跟它一起被引入的并發工具類還有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,它們都存在于java...
摘要:所有示例代碼請見下載于基本概念并發同時擁有兩個或者多個線程,如果程序在單核處理器上運行多個線程將交替地換入或者換出內存這些線程是同時存在的,每個線程都處于執行過程中的某個狀態,如果運行在多核處理器上此時,程序中的每個線程都 所有示例代碼,請見/下載于 https://github.com/Wasabi1234... showImg(https://upload-images.jians...
摘要:類大家都叫他讀寫鎖,他可以聽時刻允許多線程進入,讀寫鎖比排它鎖性能好,因為大多數情況讀多于寫。和區別同步屏障,用于多線程計算結果最后合并場景。 Java內存模型(jmm) Why:保證多線程正確協同工作 看圖說明:showImg(https://segmentfault.com/img/remote/1460000017767400); 文字解釋:線程a和線程b通信過程,首先線程...
閱讀 2657·2019-08-30 15:53
閱讀 2879·2019-08-29 16:20
閱讀 1086·2019-08-29 15:10
閱讀 1026·2019-08-26 10:58
閱讀 2198·2019-08-26 10:49
閱讀 637·2019-08-26 10:21
閱讀 707·2019-08-23 18:30
閱讀 1640·2019-08-23 15:58