并发编程-17AQS同步组件之 Semaphore 控制并发线程数的信号量
文章目錄
- J.U.C腦圖
- Semaphore 概述
- Semaphore 構(gòu)造函數(shù)及方法
- 構(gòu)造函數(shù)
- 常用和需要注意的方法
- Semaphore 示例
- acquire()
- semaphore.acquire(int permits)
- semaphore.tryAcquire()
- tryAcquire(long timeout, TimeUnit unit)
- 代碼
J.U.C腦圖
Semaphore 概述
Semaphore(信號量)是用來控制同時訪問特定資源的線程數(shù)量,它通過協(xié)調(diào)各個線程,以保證合理的使用公共資源。
舉個例子:
高速要限制流量,只允許同時有一百輛車在這條路上行使,其他的都必須 在路口等待,所以前一百輛車會看到綠燈,可以開進(jìn)這條高速,后面的車會看到紅燈,不能駛?cè)敫咚?#xff0c;但是如果前一百輛中有5輛車已經(jīng)離開了高速,那么后面就允許有5輛車駛?cè)敫咚?#xff0c;這個例子里說的車就是線程,駛?cè)敫咚倬捅硎揪€程在執(zhí)行,離開高速就表示線程執(zhí)行完成,看見紅燈就表示線程被阻塞,不能執(zhí)行。
Semaphore 構(gòu)造函數(shù)及方法
Semaphore的用法:首先線程使用Semaphore的acquire()方法獲取一個許可證,使用完之后調(diào)用release()方法歸還許可證。
構(gòu)造函數(shù)
Semaphore的構(gòu)造方法 Semaphore(int permits)接受一個整型的數(shù)字,表示可用的許可證數(shù)量。Semaphore(10)表示允許10個線程獲取許可證,也就是最大并發(fā)數(shù)是10。
第二個構(gòu)造函數(shù) Semaphore(int permits, boolean fair) 第二個構(gòu)造方法指定是公平模式還是非公平模式,默認(rèn)非公平模式 . 公平模式:先啟動的線程優(yōu)先得到許可。 非公平模式:先啟動的線程并不一定先獲得許可,誰搶到誰就獲得許可。
常用和需要注意的方法
- acquire() 獲取一個許可
- acquire(int permits) 獲取指定個數(shù)的許可
- tryAcquire()方法嘗試獲取1個許可證
- tryAcquire(long timeout, TimeUnit unit) 最大等待許可的時間
- tryAcquire(int permits) 獲取指定個數(shù)的許可
- tryAcquire(int permits, long timeout, TimeUnit unit) 最大等待許可的時間
- availablePermits() : 返回此信號量中當(dāng)前可用的許可證數(shù)
- release() 釋放許可
- release(int permits) 釋放指定個數(shù)的許可
- int getQueueLength() 返回正在等待獲取許可證的線程數(shù)。
- boolean hasQueuedThreads() 是否有線程正在等待獲取許可證。
- void reducePermits(int reduction) 減少reduction個許可證。是個protected方法。
- Collection getQueuedThreads() 返回所有等待獲取許可證的線程集合。是個protected方法。
- …
Semaphore 示例
acquire()
觀察輸出:
根據(jù)上述代碼的邏輯,test方法中休眠1秒,設(shè)置的3個許可,及同一時間最多只能有3個線程執(zhí)行,根據(jù)日志輸出的時間可以看到 符合預(yù)期。
semaphore.acquire(int permits)
輸出:
設(shè)置了3個許可,每個線程每次獲取3個許可,因此同一時間只能有1個線程執(zhí)行,輸出符合預(yù)期 。
semaphore.tryAcquire()
嘗試獲取一個許可,如果未獲取到,不等待,將直接丟棄該線程不執(zhí)行
運行輸出:
從輸出可以看到,在3個線程獲取到3個許可后,因為每個線程調(diào)用的方法要執(zhí)行1秒中,最早的一個許可也要在1S后釋放,剩下的17個線程未獲取到許可,使用了semaphore.tryAcquire()方法,沒有設(shè)置等待時間,所以便直接被丟棄,不執(zhí)行了。
tryAcquire(long timeout, TimeUnit unit)
未獲取到許可,設(shè)置等待時長
輸出結(jié)果:
tryAcquire通過參數(shù)指定了5秒的等待時間。 上述代碼中同一時間最多執(zhí)行3個。第4個線程因前3個線程執(zhí)行需要耗時一秒未釋放許可,因此需要等待。 但是由于設(shè)置了5秒的等待時間,所以在5秒內(nèi)等待到了釋放的許可,繼續(xù)執(zhí)行,循環(huán)往復(fù)。但是20個線程 ,每秒并發(fā)3個,5S是執(zhí)行不完的。,所以上面執(zhí)行到第16個(0開始,顯示是15)就結(jié)束了,【每次執(zhí)行結(jié)果會有差異,取決于CPU】,并沒有全部執(zhí)行完20個線程。
代碼
https://github.com/yangshangwei/ConcurrencyMaster
總結(jié)
以上是生活随笔為你收集整理的并发编程-17AQS同步组件之 Semaphore 控制并发线程数的信号量的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 并发编程-16AQS同步组件之Count
- 下一篇: 并发编程-19AQS同步组件之重入锁Re