<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Semaphore也是一個執行緒同步的輔助類,可以維護當前存取自身的執行緒個數,並提供了同步機制。使用Semaphore可以控制並行存取資源的執行緒個數。
例如排隊買票的情況,如果只有三個視窗,那麼同一時間最多也只能有三個人買票。第四個人來了之後就必須在後面等著,只有其他人買好了,才可以去相應的視窗進行買票 。
使用場景:僅能提供有限存取的資源。比如資料庫連線。
/** *接受一個整型的數位,表示可用的許可證數量。Semaphore(10)表*示允許10個執行緒獲取許可證, *也就是最大並行數是10。 * * @param permits 可用許可證的初始數量。 **/ public Semaphore(int permits) { sync = new NonfairSync(permits); } /** * 使用給定的許可數量和給定的公平性設定 * * @param permits 可用許可證的初始數量。 * * @param fair 指定是公平模式還是非公平模式,預設非公平模式 . 公平模式:先啟動的執行緒優先得到 * 許可。 非公平模式:先啟動的執行緒並不一定先獲得許可,誰搶到誰就獲得許可。 */ public Semaphore(int permits, boolean fair) { sync = fair ? new FairSync(permits) : new NonfairSync(permits); }
acquire() 獲取一個許可
acquire(int permits) 獲取指定個數的許可
tryAcquire()方法嘗試獲取1個許可證
tryAcquire(long timeout, TimeUnit unit) 最大等待許可的時間
tryAcquire(int permits) 獲取指定個數的許可
tryAcquire(int permits, long timeout, TimeUnit unit) 最大等待許可的時間
availablePermits() : 返回此號誌中當前可用的許可證數
release() 釋放許可
release(int permits) 釋放指定個數的許可
int getQueueLength() 返回正在等待獲取許可證的執行緒數。
boolean hasQueuedThreads() 是否有執行緒正在等待獲取許可證。
void reducePermits(int reduction) 減少reduction個許可證。是個protected方法。
Collection getQueuedThreads() 返回所有等待獲取許可證的執行緒集合。是個protected方法。
/** * 執行緒數量 */ private final static int threadCount = 15; public static void main(String[] args) throws Exception { ExecutorService exec = Executors.newCachedThreadPool(); final Semaphore semaphore = new Semaphore(3); for (int i = 0; i < threadCount; i++) { final int threadNum = i; exec.execute(() -> { try { //獲取一個許可 semaphore.acquire(); test(threadNum); //釋放一個許可 semaphore.release(); } catch (Exception e) { log.error("exception", e); } }); } exec.shutdown(); } private static void test(int threadNum) throws Exception { // 模擬請求的耗時操作 Thread.sleep(1000); log.info("{}", threadNum); }
輸出結果:
根據輸出結果的時間可以看出來同一時間最多隻能3個執行緒執行,符合預期
/** * 執行緒數量 */ private final static int threadCount = 15; public static void main(String[] args) throws Exception { ExecutorService exec = Executors.newCachedThreadPool(); //號誌設定為3,也就是最大並行量為3,同時只允許3個執行緒獲得許可 final Semaphore semaphore = new Semaphore(3); for (int i = 0; i < threadCount; i++) { final int threadNum = i; exec.execute(() -> { try { //獲取多個許可 semaphore.acquire(3); test(threadNum); //釋放多個許可 semaphore.release(3); } catch (Exception e) { log.error("exception", e); } }); } exec.shutdown(); } private static void test(int threadNum) throws Exception { // 模擬請求的耗時操作 Thread.sleep(1000); log.info("{}", threadNum); }
輸出結果:
設定了3個許可,每個執行緒每次獲取3個許可,因此同一時間只能有1個執行緒執行 。
tryAcquire()嘗試獲取一個許可,如果未獲取到,不等待,將直接丟棄該執行緒不執行
/** * 執行緒數量 */ private final static int threadCount = 15; public static void main(String[] args) throws Exception { ExecutorService exec = Executors.newCachedThreadPool(); //號誌設定為3,也就是最大並行量為3,同時只允許3個執行緒獲得許可 final Semaphore semaphore = new Semaphore(3); for (int i = 0; i < threadCount; i++) { final int threadNum = i; exec.execute(() -> { try { //嘗試獲取一個許可,如果未獲取到,不等待,將直接丟棄該執行緒不執行 if(semaphore.tryAcquire()) { test(threadNum); //釋放許可 semaphore.release(); } } catch (Exception e) { log.error("exception", e); } }); } exec.shutdown(); } private static void test(int threadNum) throws Exception { // 模擬請求的耗時操作 Thread.sleep(1000); log.info("{}", threadNum); }
輸出結果:
從輸出可以看到,在3個執行緒獲取到3個許可後,因為每個執行緒呼叫的方法要執行1秒中,最早的一個許可也要在1S後釋放,剩下的17個執行緒未獲取到許可,使用了semaphore.tryAcquire()方法,沒有設定等待時間,所以便直接被丟棄,不執行了。
tryAcquire(long timeout, TimeUnit unit)未獲取到許可,設定等待時長
/** * 執行緒數量 */ private final static int threadCount = 15; public static void main(String[] args) throws Exception { ExecutorService exec = Executors.newCachedThreadPool(); //號誌設定為3,也就是最大並行量為3,同時只允許3個執行緒獲得許可 final Semaphore semaphore = new Semaphore(3); for (int i = 0; i < threadCount; i++) { final int threadNum = i; exec.execute(() -> { try { //設定了獲取許可等待時間為2秒,如果兩秒後還是未獲得許可的執行緒便得不到執行 if(semaphore.tryAcquire(2000, TimeUnit.MILLISECONDS)) { test(threadNum); //釋放許可 semaphore.release(); } } catch (Exception e) { log.error("exception", e); } }); } exec.shutdown(); } private static void test(int threadNum) throws Exception { // 模擬請求的耗時操作 Thread.sleep(1000); log.info("{}", threadNum); }
輸出結果:
tryAcquire通過引數指定了2秒的等待時間。 上述程式碼中同一時間最多執行3個。第4個執行緒因前3個執行緒執行需要耗時一秒未釋放許可,因此需要等待。
但是由於設定了2秒的等待時間,所以在5秒內等待到了釋放的許可,繼續執行,迴圈往復。
但是15個執行緒 ,每秒並行3個,2S是執行不完的。所以上面執行到第6個(0開始,顯示是5)就結束了,【每次執行結果會有差異,取決於CPU】,並沒有全部執行完15個執行緒。
以上就是AQS同步元件Semaphore號誌案例剖析的詳細內容,更多關於AQS同步元件Semaphore的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45