Java學習筆記 同步輔助類

2021-07-10 19:50:11 字數 4016 閱讀 6544

countdownlatch乙個同步輔助類,在完成一組正在其他執行緒中執行的操作之前,它允許乙個或多個執行緒一直等待。

countdownlatch中兩個比較關鍵的方法:

public void await() throws interruptedexception; //呼叫await()方法的執行緒會被掛起,它會等待直到count值為0才繼續執行

public boolean await(long timeout, timeunit unit) throws interruptedexception; //和await()類似,只不過等待一定的時間後count值還沒變為0的話就會繼續執行

public void countdown(); //將count值減1

countdownlatch是乙個計數器,它的構造方法中需要設定乙個數值,用來設定計數的次數。每次呼叫countdown()方法之後,這個計數器都會減去1,countdownlatch會一直阻塞著呼叫await()方法的執行緒,直到計數器的值變為0。

設想有這樣乙個功能需要thread1、thread2、thread3、thread4四條線程分別統計c、d、e、f四個盤的大小,所有執行緒都統計完畢交給主線程去做彙總,利用countdownlatch來完成就非常輕鬆。

public class countdownlatchtest  catch (interruptedexception e) 

});}

// 主線程一直被阻塞,知道count的計數器被設定為0

count.await();

system.out.printf("%s時全部任務都完成,執行合併計算.\n", new date().tostring());

service.shutdown();

}}

barrier在英語中是屏障的意思,這個同步工具會阻塞呼叫的執行緒,直到條件滿足時,阻塞的執行緒同時被開啟。

public int await() throws interruptedexception, brokenbarrierexception;

public int await(long timeout, timeunit unit)throws interruptedexception,brokenbarrierexception,timeoutexception;

cyclicbarrier初始化的時候,設定乙個屏障數。執行緒呼叫await()方法的時候,這個執行緒就會被阻塞,當呼叫await()的執行緒數量到達屏障數的時候,主線程就會取消所有被阻塞執行緒的狀態。

在cyclicbarrier的構造方法中,還可以設定乙個barrieraction。

在所有的屏障都到達之後,會啟動乙個執行緒來執行這裡面的**。這裡舉乙個例子:百公尺賽跑的運動員起跑前需要準備,所有選手準備完畢之後,才可以同時起跑。

public class cyclicbarriertest 

service.shutdown();

}}// 運動員類

public class runner implements runnable

@override

public void run() catch (interruptedexception | brokenbarrierexception e)

}}

輸出:

1號選手準備完畢,準備時間0

4號選手準備完畢,準備時間0

5號選手準備完畢,準備時間1

8號選手準備完畢,準備時間1

3號選手準備完畢,準備時間2

2號選手準備完畢,準備時間3

7號選手準備完畢,準備時間3

6號選手準備完畢,準備時間3

7號選手於sun mar 27 21:19:00 cst 2016時起跑!

2號選手於sun mar 27 21:19:00 cst 2016時起跑!

5號選手於sun mar 27 21:19:00 cst 2016時起跑!

6號選手於sun mar 27 21:19:00 cst 2016時起跑!

3號選手於sun mar 27 21:19:00 cst 2016時起跑!

8號選手於sun mar 27 21:19:00 cst 2016時起跑!

4號選手於sun mar 27 21:19:00 cst 2016時起跑!

1號選手於sun mar 27 21:19:00 cst 2016時起跑!

相比countdownlatch,cyclicbarrier是可以被迴圈使用的,而且遇到執行緒中斷等情況時,還可以利用reset()方法,重置計數器,從這些方面來說,cyclicbarrier會比countdownlatch更加靈活一些。

semaphore被用於控制特定資源在同乙個時間被訪問的個數。類似連線池的概念,保證資源可以被合理的使用。

semaphore的幾個重要方法:

public void acquire() throws interruptedexception; //獲取乙個許可

public void acquire(int permits) throws interruptedexception; //獲取permits個許可

public void release(); //釋放乙個許可。注意,在釋放許可之前,必須先獲獲得許可。

public void release(int permits); //釋放permits個許可

//以上4個方法都會被阻塞,如果想立即得到執行結果,可以使用下面幾個方法:

public boolean tryacquire(); //嘗試獲取乙個許可,若獲取成功,則立即返回true,若獲取失敗,則立即返回false

public boolean tryacquire(long timeout, timeunit unit) throws interruptedexception; //嘗試獲取乙個許可,若在指定的時間內獲取成功,則立即返回true,否則則立即返回false

public boolean tryacquire(int permits); //嘗試獲取permits個許可,若獲取成功,則立即返回true,若獲取失敗,則立即返回false

public boolean tryacquire(int permits, long timeout, timeunit unit) throws interruptedexception; //嘗試獲取permits個許可,若在指定的時間內獲取成功,則立即返回true,否則則立即返回false

semaphore的構造方法可以設定乙個int值來設定乙個計數器,用於表示資源同時可以被多少外部環境使用。每使用一次acquire(),計數器都會去減去一,而每次呼叫release()計數器則會增加一。當計數器的值為0的時候,外部的環境被阻塞,直到semaphore有空閒的資源可以被使用。

public class semaphoretest  catch (interruptedexception e) 

});}

service.shutdown();

}}

執行的結果就是:

sun mar 27 20:18:16 cst 2016時獲取資源,並呼叫.

sun mar 27 20:18:16 cst 2016時獲取資源,並呼叫.

sun mar 27 20:18:16 cst 2016時獲取資源,並呼叫.

sun mar 27 20:18:19 cst 2016時獲取資源,並呼叫.

sun mar 27 20:18:19 cst 2016時獲取資源,並呼叫.

sun mar 27 20:18:19 cst 2016時獲取資源,並呼叫.

sun mar 27 20:18:22 cst 2016時獲取資源,並呼叫.

sun mar 27 20:18:22 cst 2016時獲取資源,並呼叫.

sun mar 27 20:18:22 cst 2016時獲取資源,並呼叫.

雖然執行緒池允許6個最大執行緒數量,但是同乙個時間內只用三個任務被執行。

同步輔助類CountDownLatch

問題 前段時間寫乙個多執行緒的爬蟲程式,要求在所有爬蟲執行緒執行結束後,執行資料庫插入操作。所以就要知道那些爬蟲執行緒什麼時候能夠全部停止。解決 1 按照以往的我的寫法,我習慣用thread類的activecount 方法,這個方法能夠返回當前執行緒組裡活動執行緒的數量。比如我開5個執行緒,加上主線...

Java中的5種同步輔助類

概述 當你使用synchronized關鍵字的時候,是通過互斥器來保障線程安全以及對共享資源的同步訪問。執行緒間也經常需要更進一步的協調執行,來完成複雜的併發任務,比如wait notify模式就是一種在多執行緒環境下的協調執行機制。通過api來獲取和釋放鎖 使用互斥器 或者呼叫wait notif...

多執行緒同步輔助類

同步輔助類之訊號量 允許指定共享資源數量,可以允許指定數量的執行緒同時訪問資源 與同步的區別在於,同步時,一次只能乙個執行緒訪問資源 author administrator public class semaphoredemo catch interruptedexception e start ...