13-JUC中的Semaphore(信號量)


synchronized和重入鎖ReentrantLock,這2種鎖一次都只能允許一個線程訪問一個資源,而信號量可以控制有多少個線程可以訪問特定的資源。

Semaphore常用場景:限流

比如有個停車場,有5個空位,門口有個門衛,手中5把鑰匙分別對應5個車位上面的鎖,來一輛車,門衛會給司機一把鑰匙,然後進去找到對應的車位停下來,出去的時候司機將鑰匙歸還給門衛。停車場生意比較好,同時來了100兩車,門衛手中只有5把鑰匙,同時只能放5輛車進入,其他車只能等待,等有人將鑰匙歸還給門衛之後,才能讓其他車輛進入

上面的例子中門衛就相當於Semaphore,車鑰匙就相當於許可證,車就相當於線程。

Semaphore主要方法

  • Semaphore(int permits):構造方法,參數表示許可證數量,用來創建信號量
  • Semaphore(int permits,boolean fair):構造方法,當fair等於true時,創建具有給定許可數的計數信號量並設置爲公平信號量
  • void acquire() throws InterruptedException:從此信號量獲取1個許可前線程將一直阻塞,相當於一輛車佔了一個車位,此方法會響應線程中斷,表示調用線程的interrupt方法,會使該方法拋出InterruptedException異常
  • void acquire(int permits) throws InterruptedException :和acquire()方法類似,參數表示需要獲取許可的數量;比如一個大卡車要入停車場,由於車比較大,需要申請3個車位纔可以停放
  • void acquire(int permits) throws InterruptedException :和acquire()方法類似,參數表示需要獲取許可的數量;比如一個大卡車要入停車場,由於車比較大,需要申請3個車位纔可以停放
  • boolean tryAcquire():嘗試獲取1個許可,不管是否能夠獲取成功,都立即返回,true表示獲取成功,false表示獲取失敗
  • boolean tryAcquire(int permits):和tryAcquire(),表示嘗試獲取permits個許可
  • boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException:嘗試在指定的時間內獲取1個許可,獲取成功返回true,指定的時間過後還是無法獲取許可,返回false
  • boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException:和tryAcquire(long timeout, TimeUnit unit)類似,多了一個permits參數,表示嘗試獲取permits個許可
  • void release():釋放一個許可,將其返回給信號量,相當於車從停車場出去時將鑰匙歸還給門衛
  • void release(int n):釋放n個許可
  • int availablePermits():當前可用的許可數

總結

  1. Semaphore默認創建的是非公平的信號量,什麼意思呢?這個涉及到公平與非公平。舉個例子:5個車位,允許5個車輛進去,來了100輛車,只能進去5輛,其他95在外面排隊等着。裏面剛好出來了1輛,此時剛好又來了10輛車,這10輛車是直接插隊到其他95輛前面去,還是到95輛後面去排隊呢?讓新來的去排隊就表示公平,直接去插隊爭搶第一個,就表示不公平。對於停車場,排隊肯定更好一些。不過對於信號量來說不公平的效率更高一些,所以默認是不公平的。
  2. 方法中帶有 throwsInterruptedException聲明的,表示這個方法會響應線程中斷信號,什麼意思?表示調用線程的 interrupt()方法後,會讓這些方法觸發 InterruptedException異常,即使這些方法處於阻塞狀態,也會立即返回,並拋出 InterruptedException異常,線程中斷信號也會被清除。

參考

第15天:JUC中的Semaphore(信號量)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章