AQS的幾個同步元件

2022-08-19 16:06:17 字數 2466 閱讀 1492

乙個執行緒或多個執行緒一直等待,直到其他執行緒執行的操作完成才繼續執行。

應用:平行計算。

計數器是不能重計的,計數值不能往上加,類似操作只有一次。

使用時首先new乙個countdownlatch,構造方法中放入計數,然後在乙個執行緒中呼叫await方法,這個執行緒就會進入等待狀態,其他執行緒中呼叫countdown方法減少這個計數,直至降到0時,await方法阻塞的執行緒會被喚醒繼續工作,為保證順利執行,countdown方法一定要放在finally塊裡保證。

countdownlatch的await方法還可以設定超時時間,第一引數是數字,第二個是單位,超過這個時間await的執行緒就會被喚醒,之前給定的執行緒還會繼續執行完。

控制某個資源可以被多少個執行緒訪問

應用場景:資源有限的併發控制,如資料庫連線。

使用時首先new乙個semaphere,然後引數為可以併發訪問的個數,如20。

acquire方法和release方法可以同時獲取或釋放多個許可,傳入許可數當做方法引數即可。

還可以完成這樣的場景,如果參與競爭的執行緒沒有獲得許可就直接放棄,可以在if語句中放入tryacquire方法,如果獲取許可執行操作,沒有獲取就可以放棄或者執行對應操作。

tryacquire方法可以嘗試獲取多個許可,還可以傳入時間引數,表示沒有獲取可以等一段時間,如果還是沒有再返回false。

可以實現多個執行緒相互等待,當所有執行緒就緒後,各執行緒才能接下來執行後面的操作。

應用場景:多執行緒計算

它和countdownlatch區別:它可以迴圈使用、它是多個執行緒相互等待。

當乙個執行緒呼叫await方法時,計數器的值加1,直至計數器加到對應值了,然後釋放所有執行緒,計數器又變回0,可以重用。

首先new乙個cyclicbarrier,把引數傳入代表釋放的標記值是多少。然後各執行緒執行時呼叫await方法進行阻塞,呼叫await方法一次標記就會加一,直到到要求的值就將全部阻塞執行緒釋放,一起執行。cyclicbarrier構造方法中也可以加乙個runnable,其中的任務當到達標記值時優先執行,執行完之後再釋放其他執行緒。

await方法也可以設定時間引數,過了這個時間也會自動喚醒當前執行緒,但是在執行過程中方法會丟擲brokenbarrierexception,要把異常catch住然後繼續執行,這樣就能實現自動喚醒。

用於兩個執行緒交換值然後繼續執行。

新建乙個exchanger物件,它是有泛型的,泛型的型別就是要交換值的型別。然後執行緒1呼叫其exchange方法將要交換的值1傳入,然後執行緒1進入阻塞狀態等待執行緒2交換。執行緒2呼叫exchange方法將要交換的值2傳入,然後執行緒1獲得該值同時執行緒2也拿到了值1.兩個執行緒繼續執行。

exchange方法還可以傳時間+時間單位進去,意思就是等待一段時間如果執行緒2還不交換就直接返回。

這個框架是為了解決平行計算小問題然後彙總的這類問題。採用工作竊取演算法,為每個執行緒分配乙個佇列,各個執行緒從各自的佇列頭部中取任務然後執行,如果某個執行緒先執行完對應的佇列就從其他執行緒的佇列尾端取任務執行,只有當佇列中有乙個任務時才有可能產生競爭關係,這個演算法充分利用了多執行緒的優勢進行平行計算,並減少了執行緒間的競爭。這個框架使用還有一些限制:

1、只能用fork/join來控制線程,否則會破壞執行緒機制

2、任務不能執行io操作

3、任務不能丟擲異常

使用時首先建立乙個forkjoinpool物件,然後構造乙個計算類a實現recursivetask介面,重寫compute方法,這個方法返回值就是計算結果,然後new乙個a物件,將a物件提交到pool中,得到乙個future物件,然後future呼叫get就能獲取計算結果。在compute方法計算中,應用劃分問題的思想,對於大問題劃分為小問題,小問題計算後將結果直接return,大問題劃分時直接新建a物件,然後該物件呼叫fork方法開始計算,用join方法獲取計算結果,將結果彙總返回。

建立乙個類forkjointask1繼承recursivetask介面,重寫compute方法,在這個方法內的邏輯就是如果問題大就細化問題,建立小問題的forkjointask1,然後呼叫fork和join方法得到小問題的結果,最後得到大問題的值。如果是小問題就直接計算不必拆分。

public class forkjointask1 extends recursivetask

@override

protected integer compute()

}else

return sum;

}}

呼叫時首先建立forkjoinpool物件,然後建立任務類forkjointask1,將任務物件提交到pool中得到乙個future,get取到結果。

forkjoinpool pool = new forkjoinpool();

forkjointask1 task = new forkjointask1(1, 100);

futureresult = pool.submit(task);

system.out.println(result.get());

Java之 AQS在幾個同步工具類中的使用

工具類 工具類作用 工具類加鎖方法 工具類釋放鎖方法 sync覆蓋的方法 sync非覆蓋的重要方法 state的作用 鎖型別鎖維護 semaphore 控制同時訪問某個特定資源的運算元量 acquire 每次請求乙個許可都會導致計數器減少1,一旦達到了0,新的許可請求執行緒將被掛起 release ...

AQS同步工具類對比

工具類 工具類作用 工具類加鎖方法 工具類釋放鎖方法 sync覆蓋的方法 sync非覆蓋的重要方法 state的作用 鎖型別鎖維護 semaphore 控制同時訪問某個特定資源的運算元量 acquire 每次請求乙個許可都會導致計數器減少1,一旦達到了0,新的許可請求執行緒將被掛起 release ...

併發程式設計之AQS的同步原理

aqs abstractqueuedsynchronizer 抽象佇列同步器。aqs的同步狀態 aqs使用乙個int成員變數來表示同步狀態,通過內建的fifo佇列來完成獲取資源執行緒的排隊工作。aqs使用cas對該同步狀態進行原子操作實現對其值的修改。private volatile int sta...