Java併發程式設計系列 CyclicBarrier

2021-08-08 20:19:06 字數 2470 閱讀 4247

cyclicbarrier簡介

cyclicbarrier也是基於reentrantlock和condition的乙個同步工具類,它的作用是讓一些執行緒到達某個公共屏障點時,等待未到達的執行緒。當所有執行緒到達屏障點時,繼續往下執行。

先看乙個例子

public

class

cyclicbarrierdemo

implements

runnable

@override

public

void

run(

)catch

(exception e)

}public

static

void

main

(string[

] args)

throws ioexception

system.in.

read()

;}}

實現原理

和其他同步工具不同的是,它的內部並沒有繼承aqs的內部類sync。

private

static

class

generation

//同步操作鎖

private

final reentrantlock lock =

newreentrantlock()

;//執行緒***

private

final condition trip = lock.

newcondition()

;// 等待的執行緒數

private

final

int parties;

// 所有執行緒到達後執行的任務

private

final runnable barriercommand;

// 屏障代

private generation generation =

newgeneration()

;// 還能阻塞的執行緒數

private

int count;

public

cyclicbarrier

(int parties, runnable barrieraction)

# await

cyclicbarrier最重要的方法就是await了,它的作用在例子中已經體會到了,下面進入**看看它到底是如何實現的。

private

intdowait

(boolean timed,

long nanos)

throws interruptedexception, brokenbarrierexception,timeoutexception

// 前面都是條件判斷,等待的執行緒數減1

int index =

--count;

if(index ==0)

finally

}for(;

;)catch

(interruptedexception ie)

else}if

(g.broken)

//如果執行緒因為破壞屏障操作而被喚醒則丟擲異常

throw

newbrokenbarrierexception()

;if(g != generation)

//如果執行緒因為換代操作而被喚醒則返回計數器的值

return index;

if(timed && nanos <=

0l)}

}finally

}

邏輯較長總結一下:

如果當前執行緒不是最後乙個執行緒,也就是說count不為0時,根據呼叫的await是否為限時等待,呼叫condition的await方法,此時執行緒釋放鎖,進入condition的等待佇列(aqs那篇文章中講過),當它被喚醒時需要判斷當前屏障是否被破壞,並且判斷屏障是否換代。

總結一下什麼時候會破壞屏障:

a. 某乙個執行緒被中斷

b. 屏障任務執行失敗

c. 屏障換代

d. 等待時間設定小於0

e. 呼叫reset方法重置

什麼時候會換代:

a. 當所有執行緒都到達屏障,並且任務成功執行

b. 呼叫reset方法

2. 如果當前執行緒是最後乙個到達屏障的執行緒,那麼先執行任務,然後對屏障換代,執行nextgeneration方法。

private

void

nextgeneration()

private

void

breakbarrier()

至此cyclicbarrier已經講述完畢,最後一點cyclicbarrier可以復用,即當屏障使用完一次之後,自動的重置執行緒數。但是countdownlach則不會重置計數器。

Java併發程式設計系列 CountDownLatch

countdownlatch簡介 countdownlatch是基於aqs實現的乙個執行緒同步工具,也稱為閉鎖。它的作用是讓乙個或者多個執行緒等待某個事件的發生。簡單的理解為countdownlatch有乙個正數計數器,countdown方法對計數器做減操作,await方法等待計數器達到0。所有aw...

Java的高併發程式設計系列(三)

鎖定某物件o,如果o的屬性發生改變,不影響鎖的使用,但是如果o變成另外乙個物件,則鎖定的物件發生改變,應該避免將鎖定物件的引用變成另外乙個物件。public class demo17 catch interruptedexception e system.out.println thread.cur...

JAVA併發程式設計

通過常量字串 string 來呼叫 wait 或 notify 方法所導致的問題是,jvm 編譯器會在內部自動將內容相同的 string 轉變為相同的物件。這意味著,即便你建立了兩個不同的 mywaitnotify 例項,他們內部的 mymonitorobject 變數也會指向相同的 string ...