您好,登錄后才能下訂單哦!
本篇內容主要講解“Java中的Semaphore信號量的使用方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java中的Semaphore信號量的使用方法”吧!
Semaphore 可以很輕松完成信號量控制,Semaphore可以控制某個資源可被同時訪問的個數,通過 acquire() 獲取一個許可,如果沒有就等待,而 release() 釋放一個許可。
Semaphore
Semaphore 有兩個構造函數,參數為許可的個數 permits 和是否公平競爭 fair。通過 acquire 方法能夠獲得的許可個數為 permits,如果超過了這個個數,就需要等待。當一個線程 release 釋放了一個許可后,fair 決定了正在等待的線程該由誰獲取許可,如果是公平競爭則等待時間最長的線程獲取,如果是非公平競爭則隨機選擇一個線程獲取許可。不傳 fair 的構造函數默認采用非公開競爭。
Semaphore(int permits)
Semaphore(int permits, boolean fair)
一個線程可以一次獲取一個許可,也可以一次獲取多個。 在 acquire 等待的過程中,如果線程被中斷,acquire 會拋出中斷異常,如果希望忽略中斷繼續等待可以調用 acquireUninterruptibly 方法。同時提供了 tryAcquire 方法嘗試獲取,獲取失敗返回 false,獲取成功返回 true。tryAcquire 方法可以在獲取不到時立即返回,也可以等待一段時間。需要注意的是,沒有參數的 tryAcquire 方法在有許可可以獲取的情況下,無論有沒有線程在等待都能立即獲取許可,即便是公平競爭也能立即獲取。
public void acquire()
public void acquireUninterruptibly()
public boolean tryAcquire()
public boolean tryAcquire(long timeout, TimeUnit unit)
public void release()
public void acquire(int permits)
public void acquireUninterruptibly(int permits)
public boolean tryAcquire(int permits)
public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
public void release(int permits)
使用示例
如下的示例中,測試方法 test 創建了多個線程,每個線程啟動后都調用 acquire 方法,然后延時 5s 模仿業務耗時,最后調用 release 方法釋放許可。
public class SemaphoreTest {
private int threadNum;
private Semaphore semaphore;
public SemaphoreTest(int permits,int threadNum, boolean fair) {
this.threadNum = threadNum;
semaphore = new Semaphore(permits,fair);
}
private void println(String msg){
SimpleDateFormat sdf = new SimpleDateFormat("[YYYY-MM-dd HH:mm:ss.SSS] ");
System.out.println(sdf.format(new Date()) + msg);
}
public void test(){
for(int i = 0; i < threadNum; i ++){ new Thread(() -> {
try {
semaphore.acquire();
println(Thread.currentThread().getName() + " acquire");
Thread.sleep(5000);//模擬業務耗時
println(Thread.currentThread().getName() + " release");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
公平與非公平
在上述的示例中,如果 fair 傳的是 true,則各個線程公平競爭,即按照等待時間的長短決定誰先獲取許可。以 9 個線程競爭 3 個許可為例,執行結果如下,首選是線程 0、1、2 獲取了許可,5s 后線程 3、4、5 獲取了許可,最后是線程 6、7、8 獲取許可,順序基本上與創建線程并啟動的先后順序一致,也與各個線程等待的時間基本相符。
[2017-08-20 21:47:21.817] Thread-0 acquire
[2017-08-20 21:47:21.817] Thread-2 acquire
[2017-08-20 21:47:21.817] Thread-1 acquire
[2017-08-20 21:47:26.830] Thread-1 release
[2017-08-20 21:47:26.830] Thread-0 release
[2017-08-20 21:47:26.830] Thread-4 acquire
[2017-08-20 21:47:26.830] Thread-3 acquire
[2017-08-20 21:47:26.831] Thread-2 release
[2017-08-20 21:47:26.831] Thread-5 acquire
[2017-08-20 21:47:31.831] Thread-4 release
[2017-08-20 21:47:31.831] Thread-3 release
[2017-08-20 21:47:31.831] Thread-6 acquire
[2017-08-20 21:47:31.831] Thread-7 acquire
[2017-08-20 21:47:31.832] Thread-5 release
[2017-08-20 21:47:31.832] Thread-8 acquire
[2017-08-20 21:47:36.831] Thread-6 release
[2017-08-20 21:47:36.831] Thread-7 release
[2017-08-20 21:47:36.832] Thread-8 release
在上述的示例中,如果 fair 傳的是 false,則各個線程非公平競爭,隨機選取一個線程獲取許可。以 9 個線程競爭 3 個許可為例,執行結果如下,首先是線程 0、1、3 獲取了許可,5s 后線程 2、5、7 獲取了許可,最后是線程 4、6、8 獲取許可,與線程創建啟動時間無關,也與線程等待時間無關。
[2017-08-20 17:45:09.893] Thread-0 acquire
[2017-08-20 17:45:09.893] Thread-3 acquire
[2017-08-20 17:45:09.893] Thread-1 acquire
[2017-08-20 17:45:14.895] Thread-3 release
[2017-08-20 17:45:14.895] Thread-0 release
[2017-08-20 17:45:14.895] Thread-5 acquire
[2017-08-20 17:45:14.895] Thread-1 release
[2017-08-20 17:45:14.896] Thread-7 acquire
[2017-08-20 17:45:14.896] Thread-2 acquire
[2017-08-20 17:45:19.895] Thread-5 release
[2017-08-20 17:45:19.895] Thread-4 acquire
[2017-08-20 17:45:19.896] Thread-7 release
[2017-08-20 17:45:19.896] Thread-6 acquire
[2017-08-20 17:45:19.896] Thread-2 release
[2017-08-20 17:45:19.896] Thread-8 acquire
[2017-08-20 17:45:24.895] Thread-4 release
[2017-08-20 17:45:24.896] Thread-8 release
[2017-08-20 17:45:24.896] Thread-6 release
到此,相信大家對“Java中的Semaphore信號量的使用方法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。