本篇內(nèi)容主要講解“Java中的Semaphore信號量的使用方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Java中的Semaphore信號量的使用方法”吧!
成都創(chuàng)新互聯(lián)是專業(yè)的和龍網(wǎng)站建設(shè)公司,和龍接單;提供成都做網(wǎng)站、成都網(wǎng)站設(shè)計、成都外貿(mào)網(wǎng)站建設(shè),網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行和龍網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊,希望更多企業(yè)前來合作!
Semaphore 可以很輕松完成信號量控制,Semaphore可以控制某個資源可被同時訪問的個數(shù),通過 acquire() 獲取一個許可,如果沒有就等待,而 release() 釋放一個許可。
Semaphore
Semaphore 有兩個構(gòu)造函數(shù),參數(shù)為許可的個數(shù) permits 和是否公平競爭 fair。通過 acquire 方法能夠獲得的許可個數(shù)為 permits,如果超過了這個個數(shù),就需要等待。當(dāng)一個線程 release 釋放了一個許可后,fair 決定了正在等待的線程該由誰獲取許可,如果是公平競爭則等待時間最長的線程獲取,如果是非公平競爭則隨機(jī)選擇一個線程獲取許可。不傳 fair 的構(gòu)造函數(shù)默認(rèn)采用非公開競爭。
Semaphore(int permits)
Semaphore(int permits, boolean fair)
一個線程可以一次獲取一個許可,也可以一次獲取多個。 在 acquire 等待的過程中,如果線程被中斷,acquire 會拋出中斷異常,如果希望忽略中斷繼續(xù)等待可以調(diào)用 acquireUninterruptibly 方法。同時提供了 tryAcquire 方法嘗試獲取,獲取失敗返回 false,獲取成功返回 true。tryAcquire 方法可以在獲取不到時立即返回,也可以等待一段時間。需要注意的是,沒有參數(shù)的 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 創(chuàng)建了多個線程,每個線程啟動后都調(diào)用 acquire 方法,然后延時 5s 模仿業(yè)務(wù)耗時,最后調(diào)用 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);//模擬業(yè)務(wù)耗時
println(Thread.currentThread().getName() + " release");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
公平與非公平
在上述的示例中,如果 fair 傳的是 true,則各個線程公平競爭,即按照等待時間的長短決定誰先獲取許可。以 9 個線程競爭 3 個許可為例,執(zhí)行結(jié)果如下,首選是線程 0、1、2 獲取了許可,5s 后線程 3、4、5 獲取了許可,最后是線程 6、7、8 獲取許可,順序基本上與創(chuàng)建線程并啟動的先后順序一致,也與各個線程等待的時間基本相符。
[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,則各個線程非公平競爭,隨機(jī)選取一個線程獲取許可。以 9 個線程競爭 3 個許可為例,執(zhí)行結(jié)果如下,首先是線程 0、1、3 獲取了許可,5s 后線程 2、5、7 獲取了許可,最后是線程 4、6、8 獲取許可,與線程創(chuàng)建啟動時間無關(guān),也與線程等待時間無關(guān)。
[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信號量的使用方法”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!