溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java中的Semaphore信號(hào)量的使用方法

發(fā)布時(shí)間:2021-08-30 09:50:00 來(lái)源:億速云 閱讀:163 作者:chen 欄目:編程語(yǔ)言

本篇內(nèi)容主要講解“Java中的Semaphore信號(hào)量的使用方法”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Java中的Semaphore信號(hào)量的使用方法”吧!

  Semaphore 可以很輕松完成信號(hào)量控制,Semaphore可以控制某個(gè)資源可被同時(shí)訪問的個(gè)數(shù),通過 acquire() 獲取一個(gè)許可,如果沒有就等待,而 release() 釋放一個(gè)許可。

  Semaphore

  Semaphore 有兩個(gè)構(gòu)造函數(shù),參數(shù)為許可的個(gè)數(shù) permits 和是否公平競(jìng)爭(zhēng) fair。通過 acquire 方法能夠獲得的許可個(gè)數(shù)為 permits,如果超過了這個(gè)個(gè)數(shù),就需要等待。當(dāng)一個(gè)線程 release 釋放了一個(gè)許可后,fair 決定了正在等待的線程該由誰(shuí)獲取許可,如果是公平競(jìng)爭(zhēng)則等待時(shí)間最長(zhǎng)的線程獲取,如果是非公平競(jìng)爭(zhēng)則隨機(jī)選擇一個(gè)線程獲取許可。不傳 fair 的構(gòu)造函數(shù)默認(rèn)采用非公開競(jìng)爭(zhēng)。

  Semaphore(int permits)

  Semaphore(int permits, boolean fair)

  一個(gè)線程可以一次獲取一個(gè)許可,也可以一次獲取多個(gè)。 在 acquire 等待的過程中,如果線程被中斷,acquire 會(huì)拋出中斷異常,如果希望忽略中斷繼續(xù)等待可以調(diào)用 acquireUninterruptibly 方法。同時(shí)提供了 tryAcquire 方法嘗試獲取,獲取失敗返回 false,獲取成功返回 true。tryAcquire 方法可以在獲取不到時(shí)立即返回,也可以等待一段時(shí)間。需要注意的是,沒有參數(shù)的 tryAcquire 方法在有許可可以獲取的情況下,無(wú)論有沒有線程在等待都能立即獲取許可,即便是公平競(jìng)爭(zhēng)也能立即獲取。

  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)

  使用示例

  如下的示例中,測(cè)試方法 test 創(chuàng)建了多個(gè)線程,每個(gè)線程啟動(dòng)后都調(diào)用 acquire 方法,然后延時(shí) 5s 模仿業(yè)務(wù)耗時(shí),最后調(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ù)耗時(shí)

  println(Thread.currentThread().getName() + " release");

  semaphore.release();

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  }).start();

  }

  }

  }

  公平與非公平

  在上述的示例中,如果 fair 傳的是 true,則各個(gè)線程公平競(jìng)爭(zhēng),即按照等待時(shí)間的長(zhǎng)短決定誰(shuí)先獲取許可。以 9 個(gè)線程競(jìng)爭(zhēng) 3 個(gè)許可為例,執(zhí)行結(jié)果如下,首選是線程 0、1、2 獲取了許可,5s 后線程 3、4、5 獲取了許可,最后是線程 6、7、8 獲取許可,順序基本上與創(chuàng)建線程并啟動(dòng)的先后順序一致,也與各個(gè)線程等待的時(shí)間基本相符。

  [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,則各個(gè)線程非公平競(jìng)爭(zhēng),隨機(jī)選取一個(gè)線程獲取許可。以 9 個(gè)線程競(jìng)爭(zhēng) 3 個(gè)許可為例,執(zhí)行結(jié)果如下,首先是線程 0、1、3 獲取了許可,5s 后線程 2、5、7 獲取了許可,最后是線程 4、6、8 獲取許可,與線程創(chuàng)建啟動(dòng)時(shí)間無(wú)關(guān),也與線程等待時(shí)間無(wú)關(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

到此,相信大家對(duì)“Java中的Semaphore信號(hào)量的使用方法”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI