Semaphore信號量計數器。和CountDownLatch,CyclicBarrier相似,是多線程協做的工具類,相對於join,wait,notify方法使用起來簡單高效。下面咱們主要看看它的用法吧!java
好比在一個系統中同時只能保證5個用戶同時在線。微信
import java.util.concurrent.Semaphore; /** * @author :jiaolian * @date :Created in 2021-03-04 11:13 * @description:Semaphore限流 * @modified By: * 公衆號:叫練 */ public class LimitCurrnet { public static void main(String[] args) throws InterruptedException { //定義20個線程,每次最多隻能執行5個線程; Semaphore semaphore = new Semaphore(5); for (int i=0; i<20; i++) { new Thread(()->{ try { //獲取憑證 semaphore.acquire(); System.out.println(Thread.currentThread().getName()+"登陸成功"); Thread.sleep(2000); //釋放憑證 semaphore.release(); System.out.println(Thread.currentThread().getName()+"用戶退出"); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } } }
如上代碼所示:咱們定義了20個用戶同時訪問系統,Semaphore參數是5,表示同時只能有5個用戶能夠獲取憑證,其餘用戶必須等待直到有在線用戶退出。調用semaphore.acquire()表示獲取憑證,此時憑證數會減一,調用semaphore.release()表示釋放憑證,憑證數會加一,若是系統中有等待的用戶,操做此方法會通知等待的一個用戶獲取憑證成功,執行登陸操做。最後打印部分結果以下:證實系統最多能保持5個用戶同時在線。多線程
注意:上面舉出的這個案例,出個思考題:線程池是否能夠實現呢?併發
Semaphore能夠輕鬆實現CountDownLatch計數器,CyclicBarrier迴環屏障,還記得CountDownLatch用法麼?它是個計數器,能夠幫咱們統計線程執行時間,經常使用來測試多線程高併發執行接口效率,咱們下面用Semaphore模擬多線程主線程等待子線程執行完畢再返回。ide
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; /** * @author :jiaolian * @date :Created in 2021-03-01 21:04 * @description:信號量測試 * @modified By: * 公衆號:叫練 */ public class SemaphoreTest { //定義線程數量; private static final int THREAD_COUNT = 2; //初始化信號量爲0,默認是非公平鎖 private static Semaphore semaphore = new Semaphore(0,false); private static ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT); public static void main(String[] args) throws InterruptedException { for (int i=0; i<THREAD_COUNT; i++) { executorService.submit(()->{ try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"執行"); semaphore.release(); }); } //獲取2個信號量 semaphore.acquire(2); System.out.println("主線程執行完畢"); executorService.shutdown(); } }
如上代碼所示:咱們定義了Semaphore初始化信號量爲0,默認是非公平鎖,在主線程中用線程池提交2個線程,主線程調用semaphore.acquire(2)表示須要獲取兩個信號量,但此時初始化信號量爲0,此時AQS中的state會是0-2=-2,state值小於0,因此主線程執行這句話會阻塞將其加入AQS同步隊列,線程池兩個線程等待2秒後會調用semaphore.release()釋放2個信號量,此時AQS中的state會自增到0,會通知主線程退出等待繼續往下執行。執行結果以下圖所示。高併發
有沒有發現Semaphore用法能夠模擬CountDownLatch,另外Semaphore經過調用acquire,release方法,還能夠實現CyclicBarrier功能!咱們不舉例了。工具
今天咱們介紹了Semaphore,整理出來但願能對你有幫助,寫的比不全,同時還有許多須要修正的地方,但願親們加以指正和點評,喜歡的請點贊加關注哦。點關注,不迷路,我是【叫練】公衆號,微信號【jiaolian123abc】邊叫邊練。測試