併發工具的使用

2022-06-20 19:36:07 字數 3037 閱讀 9308

之前的文章中學習了j.u.c中aqs的底層實現原理,這篇文學習一下j.u.c中提供的一些執行緒同步工具類。

在前面學習 synchronized 的時候,有講到 wait/notify 的基本使用,結合 synchronized 可以實現對執行緒的通訊。既然 j.u.c 裡面提供了鎖的實現機制,那 j.u.c 裡面有沒有提供類似的執行緒通訊的工具呢?

condition 是乙個多執行緒協調通訊的工具類,可以讓某些執行緒一起等待某個條件(condition),只有滿足條件時,執行緒才會被喚醒。

conditionwait

public

class conditiondemowait implements

runnable

@override

public

void

run()

catch

(interruptedexception e)

finally

}}conditionsignal

public

class conditiondemosignal implements

runnable

@override

public

void

run()

finally

}}

通過這個案例簡單實現了 wait 和 notify 的功能,當呼叫await 方法後,當前執行緒會釋放鎖並等待,而其他執行緒呼叫condition 物件的 signal 或者 signalall 方法通知並被阻塞的執行緒,然後自己執行 unlock 釋放鎖,被喚醒的執行緒獲得之前的鎖繼續執行,最後釋放鎖。所以,condition 中兩個最重要的方法,乙個是 await,乙個是 signal 方法

await:把當前執行緒阻塞掛起

signal:喚醒阻塞的執行緒

countdownlatch 是乙個同步工具類,它允許乙個或多個執行緒一直等待,直到其他執行緒的操作執行完畢再執行。從命名可以解讀到 countdown 是倒數的意思,類似於我們倒計時的概念。

countdownlatch 提供了兩個方法,乙個是 countdown,乙個是 await,countdownlatch 初始化的時候需要傳入乙個整數,在這個整數倒數到 0 之前,呼叫了 await 方法的程式都必須要等待,然後通過 countdown 來倒數。

public

static

void main(string args) throws

interruptedexception , "t1").start();

new thread(() ->, "t2").start();

new thread(() ->, "t3").start();

countdownlatch.await();

system.out.println("所有執行緒執行完畢");

}

從**的實現來看,有點類似 join 的功能,但是比 join 更加靈活。countdownlatch 建構函式會接收乙個 int 型別的引數作為計數器的初始值,當呼叫 countdownlatch 的countdown 方法時,這個計數器就會減一。通過 await 方法去阻塞去阻塞主流程。

semaphore 也就是我們常說的訊號燈,semaphore 可以控制同時訪問的執行緒個數,通過 acquire 獲取乙個許可,如果沒有就等待,通過 release 釋放乙個許可。有點類似限流的作用。叫訊號燈的原因也和他的用處有關,比如某商場就 5 個停車位,每個停車位只能停一輛車,如果這個時候來了 10 輛車,必須要等前面有空的車位才能進入。

public

class

test

}static

class car extends

thread

public

void

run()

catch

(interruptedexception e) }}

}

semaphore 比較常見的就是用來做限流操作了。

cyclicbarrier 的字面意思是可迴圈使用(cyclic)的屏障(barrier)。它要做的事情是,讓一組執行緒到達乙個屏障(也可以叫同步點)時被阻塞,直到最後乙個執行緒到達屏障時,屏障才會開門,所有被屏障攔截的執行緒才會繼續工作。cyclicbarrier 預設的構造方法是 cyclicbarrier(int parties),其引數表示屏障攔截的執行緒數量,每個執行緒呼叫 await 方法告訴 cyclicbarrier 當前執行緒已經到達了屏障,然後當前執行緒被阻塞。

當存在需要所有的子任務都完成時,才執行主任務,這個時候就可以選擇使用 cyclicbarrier

public

class dataimportthread extends

thread

@override

public

void

run() catch

(interruptedexception e)

catch

(brokenbarrierexception e)

}}

public class cyclibarrierdemo extends thread 

public static void main(string args)

}

1)對於指定計數值 parties,若由於某種原因,沒有足夠的執行緒呼叫 cyclicbarrier 的 await,則所有呼叫 await 的執行緒都會被阻塞;

2)同樣的 cyclicbarrier 也可以呼叫 await(timeout, unit),設定超時時間,在設定時間內,如果沒有足夠執行緒到達,則解除阻塞狀態,繼續工作;

3)通過 reset 重置計數,會使得進入 await 的執行緒出現brokenbarrierexception;

4)如果採用是 cyclicbarrier(int parties, runnable barrieraction) 構造方法,執行 barrieraction 操作的是最後乙個到達的執行緒

併發程式設計 併發工具的使用及原理

condition condition.await aqs.await 1 先addconditionwaiter 把當前節點加入到condition佇列中 等待佇列 waitstatus 2,這個入隊的流程和aqs有些類似,但是這裡沒有空的頭結點,入隊的執行緒節點自身就是頭結點,而且是單向鍊錶。2...

JUC併發工具使用案例

包含以下併發工具的呼叫 synchronized 同步鎖 reentrantlock 同步鎖 condition 執行緒通訊 reentrantreadwritelock 讀寫鎖 讀寫分離 stampedlock 讀寫鎖 悲觀 樂觀 讀的同時可以寫 atomicinteger 原子性遞增 longa...

高併發模擬工具使用記錄

伺服器資訊 阿里雲,1核2g,伺服器,網速1m ab c 10000 n 1000000主要是用於windows系統 這裡其中要說明 c代表併發的數量,n代表請求的總數,n必須大於 c。c 即是concurrency n 即是number of requests 上面的測試表示,每次有10000個請...