1. 程式人生 > >Java併發程式設計札記-(四)JUC鎖-09CyclicBarrier

Java併發程式設計札記-(四)JUC鎖-09CyclicBarrier

CyclicBarrier允許一組執行緒互相等待,直到到達某個公共屏障點。如果你希望一組並行的任務在下個步驟之前相互等待,直到所有的任務都完成了下個步驟前的所有操作,才繼續向前執行,那麼CyclicBarrier很合適。

函式列表

//構造方法摘要
CyclicBarrier(int parties) 
          //建立一個新的 CyclicBarrier,它將在給定數量的參與者(執行緒)處於等待狀態時啟動,但它不會在啟動 barrier 時執行預定義的操作。
CyclicBarrier(int parties, Runnable barrierAction) 
          //建立一個新的 CyclicBarrier,它將在給定數量的參與者(執行緒)處於等待狀態時啟動,並在啟動 barrier 時執行給定的屏障操作,該操作由最後一個進入 barrier 的執行緒執行。  
//方法摘要 int await() //在所有參與者都已經在此 barrier 上呼叫 await 方法之前,將一直等待。 int await(long timeout, TimeUnit unit) //在所有參與者都已經在此屏障上呼叫 await 方法之前將一直等待,或者超出了指定的等待時間。 int getNumberWaiting() //返回當前在屏障處等待的參與者數目。 int getParties() //返回要求啟動此 barrier 的參與者數目。 boolean isBroken() //查詢此屏障是否處於損壞狀態。
void reset() //將屏障重置為其初始狀態。

CyclicBarrier與CountDownLatch的比較
看過CyclicBarrier的方法列表後,有沒有發現CyclicBarrier與CountDownLatch比較像。它們之間最大的區別在於CyclicBarrier的計數器可以重置,相當於可以迴圈使用。cyclic,意為可迴圈的,barrier,意為屏障,剛好映照了CyclicBarrier的兩個特點。

例項1:CyclicBarrier簡單使用

public class CyclicBarrierTest {
    // 參與者數量
    private
static int parties = 3; // 建立一個新的 CyclicBarrier,它將在給定數量的參與者(執行緒)處於等待狀態時啟動 private static CyclicBarrier barrier = new CyclicBarrier(parties); public static void main(String[] args) throws InterruptedException { for (int i = 0; i < parties; i++) new Thread(new Task()).start(); Thread.sleep(1000); System.out.println("getNumberWaiting():" + barrier.getNumberWaiting()); } static class Task implements Runnable { public void run() { try { System.out.println(Thread.currentThread().getName() + "await"); // 在所有參與者都已經在此 barrier 上呼叫 await 方法之前,將一直等待。 barrier.await(); System.out.println(Thread.currentThread().getName() + "continued"); } catch (BrokenBarrierException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } }

執行結果為:
Thread-0await
Thread-1await
Thread-2await
Thread-1continued
Thread-0continued
Thread-2continued
getNumberWaiting():0

從結果中可以看到,3個任務執行緒依次啟動,但每一個都沒有執行完,這是因為run方法中的cb.await();使當前執行緒在所有參與者都已經在此barrier上呼叫await方法之前,一直等待。直到所有的參與者都已經在此barrier上呼叫await,才執行所有等待的任務。
從最後一行輸出可以看出,在所有執行緒越過屏障後,當前在屏障處等待的參與者數目變為0。

原始碼

待補充

本文就講到這裡,想了解Java併發程式設計更多內容請參考:

相關推薦

Java併發程式設計札記-()JUC-09CyclicBarrier

CyclicBarrier允許一組執行緒互相等待,直到到達某個公共屏障點。如果你希望一組並行的任務在下個步驟之前相互等待,直到所有的任務都完成了下個步驟前的所有操作,才繼續向前執行,那麼CyclicBarrier很合適。 函式列表 //構造方法摘要 Cy

Java併發程式設計札記-()JUC-08CountDownLatch

CountDownLatch是一個通用同步器,用於同步一個或多個任務。在完成一組正在其他執行緒中執行的任務之前,它允許一個或多個執行緒一直等待。 可以用一個初始計數值來初始化CountDownLatch物件,任何在這個物件上呼叫wait()的方法都將阻塞,直至

Java併發程式設計札記-()JUC-04Condition簡介

我們已經學習瞭如何通過使用鎖來同步兩個任務,但為了解決某個問題,任務之間只有互斥是不夠的,還需要相互通訊,相互協作。今天就來學習如何實現任務之間的協作。 初識Condition 在任務協作中,關鍵問題是任務之間的通訊。握手可以通過Object的監視器方法(w

Java併發程式設計札記-()JUC-01概述

今天來學習JUC鎖。JUC鎖位於java.util.concurrent.locks包下,為鎖和等待條件提供一個框架,它不同於內建同步和監視器。 參考JDK1.8的java.util.concurrent.locks包,畫出如下圖: CountDown

Java併發程式設計札記-()JUC-10Semaphore簡介

一般的鎖在任意時刻只允許一個執行緒訪問一項資源,而計數訊號量允許n個任務同時訪問一項資源。我們可以將訊號量看做一個許可集,可以向執行緒分發使用資源的許可證。獲得資源前,執行緒呼叫acquire()從許可集中獲取許可。該執行緒結束後,通過release()將許可還

Java併發程式設計札記-()JUC-02Lock與ReentrantLock

今天學習Lock與ReentrantLock。 Java中的鎖有兩種,synchronized與Lock。因為使用synchronized並不需要顯示地加鎖與解鎖,所以往往稱synchronized為隱式鎖,而使用Lock時則相反,所以一般稱Lock為顯示鎖。

Java併發程式設計札記-()JUC-07讀寫的升級—StampedLock

StampedLock是JDK1.8新增的一個鎖,是對讀寫鎖ReentrantReadWriteLock的改進。前面已經學習了ReentrantReadWriteLock,我們瞭解到,在共享資料很大,且讀操作遠多於寫操作的情況下,ReentrantReadWri

Java併發程式設計札記-(六)JUC執行緒池-01概述

前面的例子中總是需要執行緒時就建立,不需要就銷燬它。但頻繁建立和銷燬執行緒是很耗資源的,在併發量較高的情況下頻繁建立和銷燬執行緒會降低系統的效率。執行緒池可以通過重複利用已建立的執行緒降低執行緒建立和銷

Java併發程式設計札記-(五)JUC容器-05ArrayBlockingQueue與LinkedBlockingQueue

今天來學習ArrayBlockingQueue與LinkedBlockingQueue。 ArrayBlockingQueue是一個基於陣列的有界阻塞佇列。“有界”表示陣列容量是固定的。這是一個典型的“有界快取區”,固定大小的陣列在其中保持生產者插入的元素和使

Java併發程式設計札記-(二)JUC概述

從今天開始學習JUC。JUC是java.util.concurrent包的簡稱。下圖是JUC的整體結構。 atomic 以下是JUC中的原子類。 locks 以下是JUC中的鎖,也稱顯示

Java併發程式設計札記-(三)JUC原子類-07CAS

CAS,即compare and swap,比較並交換。CAS操作包含三個運算元:記憶體值(V),預期值(A)、新值(B)。如果記憶體值與預期值相同,就將記憶體值修改為新值,否則不做任何操作。 java.util.concurrent.atomic是建立在CA

Java併發程式設計札記-(五)JUC容器-03ConcurrentHashMap

今天來學習ConcurrentHashMap在JDK1.8中的實現。相比JDK1.7,JDK1.8中ConcurrentHashMap的實現有很大的不同。 結構 先來看下JDK1.7與JDK1.8中ConcurrentHashMap結構的不同。 JDK1.

Java併發程式設計札記-(三)JUC原子類-05原子方式更新類的指定volatile欄位

AtomicReferenceFieldUpdater、AtomicIntegerFieldUpdater和AtomicLongFieldUpdater是基於反射的實用工具,可以提供對關聯欄位型別的訪問。例如AtomicLongFieldUpdater可以對指定

Java併發程式設計札記-(三)JUC原子類-06JDK1.8新增:LongAdder、DoubleAdder、LongAccumulator、DoubleAccumulator

DoubleAccumulator、LongAccumulator、DoubleAdder、LongAdder是JDK1.8新增的部分,是對AtomicLong等類的改進。比如LongAccumulator與LongAdder在高併發環境下比AtomicLong

實戰Java併發程式設計的優化及注意事項)

在多核時代,使用多執行緒可以明顯地提升系統的效能。但事實上,使用多執行緒會額外增加系統的開銷。對於單任務或單執行緒的應用來說,其主要資源消耗在任務本身。對於多執行緒來說,系統除了處理功能需求外,還需要維護多執行緒環境特有的資訊,如執行緒本身的元資料,執行緒的排程,執行緒上下文的切換等。 4.1有

Java併發程式設計(10)-顯式和讀寫的使用

文章目錄 一、顯式鎖 1.1、什麼是顯式鎖 1.2、Lock和ReentrantLock 1.3、如何使用顯示鎖 二、讀寫鎖 2.1、為什麼使用讀寫鎖

Java併發程式設計)volatile關鍵字

  一、volatile特性 volatile的兩點特性:禁止重排序、保證記憶體可見性。volatile不能保證原子性。 1、禁止指令重排 原理:volatile關鍵字通過提供記憶體屏障的方式來防止指令被重排序,編譯器在生成位元組碼時,會在指令序列中插入記憶體屏障來禁止特定

Java併發程式設計)-Lock

Lock         Lock是java 1.5中引入的執行緒同步工具,它主要用於多執行緒下共享資源的控制。本質上Lock僅僅是一個介面(位於原始碼包中的java\util\concurrent\locks中),它包含以下方法 //嘗試獲取鎖,獲取成功則返回

Java併發程式設計札記-(一)基礎-01基本概念

在學習Java併發程式設計之前,先來了解一下幾個概念。 什麼是併發?維基百科中這樣介紹: 在電腦科學中,併發性是指程式,演算法或問題的不同部分或單元按無序或部分順序執行而不影響最終結果的能力。這允許並行單元的並行執行,這可以顯著提高在多處理器和多核系統

Java併發程式設計札記-(一)基礎-03執行緒的生命週期

本文主要講解Java中執行緒的狀態。Java中執行緒的狀態和作業系統中執行緒的狀態有所不同。 目錄 執行緒的生命週期 執行緒的狀態 執行緒的生命週期 此圖是根據自己的瞭解畫的,如果有不足或錯誤歡迎指正。 執行緒的狀態 Java中執行緒