成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

分析Java并發編程之信號量Semaphore

瀏覽:2日期:2022-08-10 09:43:53
目錄一、認識Semaphore1.1、Semaphore 的使用場景1.2、Semaphore 使用1.3、Semaphore 信號量的模型二、Semaphore 深入理解2.1、Semaphore 基本屬性2.2、Semaphore 的公平性和非公平性2.3、其他 Semaphore 方法一、認識Semaphore1.1、Semaphore 的使用場景

Semaphore 的使用場景主要用于流量控制,比如數據庫連接,同時使用的數據庫連接會有數量限制,數據庫連接不能超過一定的數量,當連接到達了限制數量后,后面的線程只能排隊等前面的線程釋放數據庫連接后才能獲得數據庫連接。

再比如交通公路上的紅綠燈,綠燈亮起時只能讓 100 輛車通過,紅燈亮起不允許車輛通過。

再比如停車場的場景中,一個停車場有有限數量的車位,同時能夠容納多少臺車,車位滿了之后只有等里面的車離開停車場外面的車才可以進入。

1.2、Semaphore 使用

下面我們就來模擬一下停車場的業務場景:在進入停車場之前會有一個提示牌,上面顯示著停車位還有多少,當車位為 0 時,不能進入停車場,當車位不為 0 時,才會允許車輛進入停車場。所以停車場有幾個關鍵因素:停車場車位的總容量,當一輛車進入時,停車場車位的總容量 - 1,當一輛車離開時,總容量 + 1,停車場車位不足時,車輛只能在停車場外等待。

public class CarParking { private static Semaphore semaphore = new Semaphore(10); public static void main(String[] args){for(int i = 0;i< 100;i++){ Thread thread = new Thread(new Runnable() {@Overridepublic void run() { System.out.println('歡迎 ' + Thread.currentThread().getName() + ' 來到停車場'); // 判斷是否允許停車 if(semaphore.availablePermits() == 0) {System.out.println('車位不足,請耐心等待'); } try {// 嘗試獲取semaphore.acquire();System.out.println(Thread.currentThread().getName() + ' 進入停車場');Thread.sleep(new Random().nextInt(10000));// 模擬車輛在停車場停留的時間System.out.println(Thread.currentThread().getName() + ' 駛出停車場');semaphore.release(); } catch (InterruptedException e) {e.printStackTrace(); }} }, i + '號車'); thread.start();} }}

在上面這段代碼中,我們給出了 Semaphore 的初始容量,也就是只有 10 個車位,我們用這 10 個車位來控制 100 輛車的流量,所以結果和我們預想的很相似,即大部分車都在等待狀態。但是同時仍允許一些車駛入停車場,駛入停車場的車輛,就會 semaphore.acquire 占用一個車位,駛出停車場時,就會 semaphore.release 讓出一個車位,讓后面的車再次駛入。

1.3、Semaphore 信號量的模型

上面代碼雖然比較簡單,但是卻能讓我們了解到一個信號量模型的五臟六腑。下面是一個信號量的模型:

分析Java并發編程之信號量Semaphore

來解釋一下 Semaphore ,Semaphore 有一個初始容量,這個初始容量就是 Semaphore 所能夠允許的信號量。在調用 Semaphore 中的 acquire 方法后,Semaphore 的容量 -1,相對的在調用 release 方法后,Semaphore 的容量 + 1,在這個過程中,計數器一直在監控 Semaphore 數量的變化,等到流量超過 Semaphore 的容量后,多余的流量就會放入等待隊列中進行排隊等待。等到 Semaphore 的容量允許后,方可重新進入。

Semaphore 所控制的流量其實就是一個個的線程,因為并發工具最主要的研究對象就是線程。

它的工作流程如下

分析Java并發編程之信號量Semaphore

這幅圖應該很好理解吧,這里就不再過多解釋啦。

二、Semaphore 深入理解

在了解 Semaphore 的基本使用和 Semaphore 的模型后,下面我們還是得從源碼來和你聊一聊 Semaphore 的種種細節問題,因為我寫文章最核心的東西就是想讓我的讀者 了解 xxx,看這一篇就夠了,這是我寫文章的追求,好了話不多說,源碼走起來!

2.1、Semaphore 基本屬性

Semaphore 中只有一個屬性

private final Sync sync;

Sync 是 Semaphore 的同步實現,Semaphore 保證線程安全性的方式和 ReentrantLock 、CountDownLatch 類似,都是繼承于 AQS 的實現。同樣的,這個 Sync 也是繼承于 AbstractQueuedSynchronizer 的一個變量,也就是說,聊 Semaphore 也繞不開 AQS,所以說 AQS 真的太重要了。

2.2、Semaphore 的公平性和非公平性

那么我們進入 Sync 內部看看它實現了哪些方法

abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 1192457210091910933L; Sync(int permits) { setState(permits); } final int getPermits() { return getState(); } final int nonfairTryAcquireShared(int acquires) { for (;;) { int available = getState(); int remaining = available - acquires; if (remaining < 0 || compareAndSetState(available, remaining))return remaining; } } protected final boolean tryReleaseShared(int releases) { for (;;) { int current = getState(); int next = current + releases; if (next < current) // overflowthrow new Error('Maximum permit count exceeded'); if (compareAndSetState(current, next))return true; } } final void reducePermits(int reductions) { for (;;) { int current = getState(); int next = current - reductions; if (next > current) // underflowthrow new Error('Permit count underflow'); if (compareAndSetState(current, next))return; } } final int drainPermits() { for (;;) { int current = getState(); if (current == 0 || compareAndSetState(current, 0))return current; } }}

首先是 Sync 的初始化,內部調用了 setState 并傳遞了 permits ,我們知道,AQS 中的 State 其實就是同步狀態的值,而 Semaphore 的這個 permits 就是代表了許可的數量。

getPermits 其實就是調用了 getState 方法獲取了一下線程同步狀態值。后面的 nonfairTryAcquireShared 方法其實是在 Semaphore 中構造了 NonfairSync 中的 tryAcquireShared 調用的

分析Java并發編程之信號量Semaphore

這里需要提及一下什么是 NonfairSync,除了 NonfairSync 是不是還有 FairSync 呢?查閱 JDK 源碼發現確實有。

那么這里的 FairSync 和 NonfairSync 都代表了什么?為什么會有這兩個類呢?

事實上,Semaphore 就像 ReentrantLock 一樣,也存在“公平”和'不公平'兩種,默認情況下 Semaphore 是一種不公平的信號量

分析Java并發編程之信號量Semaphore

Semaphore 的不公平意味著它不會保證線程獲得許可的順序,Semaphore 會在線程等待之前為調用 acquire 的線程分配一個許可,擁有這個許可的線程會自動將自己置于線程等待隊列的頭部。

當這個參數為 true 時,Semaphore 確保任何調用 acquire 的方法,都會按照先入先出的順序來獲取許可。

final int nonfairTryAcquireShared(int acquires) { for (;;) { // 獲取同步狀態值 int available = getState(); // state 的值 - 當前線程需要獲取的信號量(通常默認是 -1),只有 // remaining > 0 才表示可以獲取。 int remaining = available - acquires; // 先判斷是否小于 0 ,如果小于 0 則表示無法獲取,如果是正數 // 就需要使用 CAS 判斷內存值和同步狀態值是否一致,然后更新為同步狀態值 - 1 if (remaining < 0 ||compareAndSetState(available, remaining)) return remaining; }}

分析Java并發編程之信號量Semaphore

從上面這幅源碼對比圖可以看到,NonfairSync 和 FairSync 最大的區別就在于 tryAcquireShared 方法的區別。

NonfairSync 版本中,是不會管當前等待隊列中是否有排隊許可的,它會直接判斷信號許可量和 CAS 方法的可行性。

FairSync 版本中,它首先會判斷是否有許可進行排隊,如果有的話就直接獲取失敗。

這時候可能就會有讀者問了,你上面說公平性和非公平性的區別一直針對的是 acquire 方法來說的,怎么現在他們兩個主要的區別在于 tryAcquireShared 方法呢?

別急,讓我們進入到 acquire 方法一探究竟

分析Java并發編程之信號量Semaphore

可以看到,在 acquire 方法中,會調用 tryAcquireShared 方法,根據其返回值判斷是否調用 doAcquireSharedInterruptibly 方法。

這里需要注意下,acquire 方法具有阻塞性,而 tryAcquire 方法不具有阻塞性。

這也就是說,調用 acquire 方法如果獲取不到許可,那么 Semaphore 會阻塞,直到有可用的許可。而 tryAcquire 方法如果獲取不到許可會直接返回 false。

這里還需要注意下 acquireUninterruptibly 方法,其他 acquire 的相關方法要么是非阻塞,要么是阻塞可中斷,而 acquireUninterruptibly 方法不僅在沒有許可的情況下執著的等待,而且也不會中斷,使用這個方法時需要注意,這個方法很容易在出現大規模線程阻塞而導致 Java 進程出現假死的情況。

有獲取許可相對應的就有釋放許可,但是釋放許可不會區分到底是公平釋放還是非公平釋放。不管方式如何都是釋放一個許可給 Semaphore ,同樣的 Semaphore 中的許可數量會增加。

分析Java并發編程之信號量Semaphore

在上圖中調用 tryReleaseShared 判斷是否能進行釋放后,再會調用 AQS 中的 releasedShared 方法進行釋放。

分析Java并發編程之信號量Semaphore

上面這個釋放流程只是釋放一個許可,除此之外,還可以釋放多個許可

public void release(int permits) { if (permits < 0) throw new IllegalArgumentException(); sync.releaseShared(permits);}

后面這個 releaseShared 的釋放流程和上面的釋放流程一致。

2.3、其他 Semaphore 方法

除了上面基本的 acquire 和 release 相關方法外,我們也要了解一下 Semaphore 的其他方法。Semaphore 的其他方法比較少,只有下面這幾個:

drainPermits : 獲取并退還所有立即可用的許可,其實相當于使用 CAS 方法把內存值置為 0 reducePermits:和 nonfairTryAcquireShared 方法類似,只不過 nonfairTryAcquireShared 是使用 CAS 使內存值 + 1,而 reducePermits 是使內存值 - 1 。 isFair:對 Semaphore 許可的爭奪是采用公平還是非公平的方式,對應到內部的實現就是 FairSync 和 NonfairSync。 hasQueuedThreads:當前是否有線程由于要獲取 Semaphore 許可而進入阻塞。 getQueuedThreads:返回一個包含了等待獲取許可的線程集合。 getQueueLength:獲取正在排隊而進入阻塞狀態的線程個數

以上就是分析Java并發編程之信號量Semaphore的詳細內容,更多關于Java并發編程 信號量Semaphore的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
亚洲国产一区二区三区a毛片| 欧美三级网页| 伊甸园精品99久久久久久| 国产精品久久网站| 久久精品123| 国产91精品露脸国语对白| 日韩欧美一级片| 欧美日韩视频在线一区二区观看视频| 蜜臀精品久久久久久蜜臀| 91精品国产综合久久福利软件| 性做久久久久久免费观看| 欧美日韩免费精品| 91国产视频在线观看| 国产欧美一区二区精品婷婷 | 国产精品一区二区在线观看| 椎名由奈av一区二区三区| 99r国产精品| 国产视频一区不卡| 色综合天天在线| 国产网红主播福利一区二区| 97超碰欧美中文字幕| 日韩欧美精品在线| 狠狠色伊人亚洲综合成人| 精品久久久久久综合日本欧美| 国产一区美女| 国产精品的网站| 天涯成人国产亚洲精品一区av| 久久精品99久久久| 成人av网站大全| 日韩小视频在线观看专区| 久草这里只有精品视频| 欧美色视频一区| 精品制服美女久久| 欧美日韩中文国产| 国产精品自拍三区| 日韩亚洲欧美成人一区| 国产福利一区二区三区在线视频| 欧美丰满少妇xxxxx高潮对白| 蜜桃在线一区二区三区| 在线视频亚洲一区| 久久se精品一区二区| 制服.丝袜.亚洲.中文.综合| 国产精品亚洲一区二区三区妖精 | 亚洲乱码国产乱码精品精的特点 | 亚洲一区二三| 裸体歌舞表演一区二区| 91精品国产综合久久久久久久| 成人丝袜高跟foot| 久久久久久久久99精品| 国产综合婷婷| 亚洲国产乱码最新视频| 欧美三级三级三级| 国产精品1区2区| 久久久久久久久久久久电影| 国语精品中文字幕| 亚洲在线视频免费观看| 欧美视频一区二区三区在线观看| 国产成人无遮挡在线视频| 精品不卡在线视频| 99av国产精品欲麻豆| 丝袜美腿高跟呻吟高潮一区| 欧美日韩国产a| 97精品国产97久久久久久久久久久久| 综合久久久久综合| 91久久国产最好的精华液| 国产经典欧美精品| 日本一区二区三区国色天香| 中日韩男男gay无套| 奇米色777欧美一区二区| 日韩精品一区二区在线| 精品成人在线| 男女性色大片免费观看一区二区| 精品国产麻豆免费人成网站| 亚洲欧洲一区二区在线观看| 久久精品国产亚洲5555| 国产三级三级三级精品8ⅰ区| 一区二区高清| 国产一区二区三区四区五区美女| 国产欧美一区二区在线观看| 一区二区三区导航| 久久精品国产久精国产爱| 欧美xxx久久| 亚洲伦理一区| 精品一区二区综合| 中文久久乱码一区二区| 久久久99爱| 成人免费视频一区| 亚洲免费观看在线视频| 欧美精品xxxxbbbb| 在线看片一区| 国产一区二区精品在线观看| 中文字幕中文字幕在线一区 | 日韩欧美三级在线| 中文欧美日韩| 国产suv精品一区二区883| 亚洲视频在线一区| 欧美日本在线观看| 一本一本久久| 成人网页在线观看| 日韩精品三区四区| 国产日产精品1区| 91精品福利视频| 激情综合在线| 成人妖精视频yjsp地址| 亚洲mv在线观看| 久久精品在这里| 欧美撒尿777hd撒尿| 国产精品theporn| 久久精品国产99| 亚洲欧洲国产专区| 日韩一区二区三区视频在线| 国产精品欧美久久| av电影在线不卡| 蜜臀av亚洲一区中文字幕| 1024亚洲合集| 日韩欧美一区二区不卡| 久久av一区二区三区| 91丨porny丨蝌蚪视频| 日本欧美大码aⅴ在线播放| 国产精品乱码人人做人人爱| 91精品国产色综合久久不卡电影| 亚洲日韩视频| 99久久久无码国产精品| 日本中文字幕一区| 亚洲日本免费电影| 欧美大片一区二区三区| 欧美亚洲综合网| 亚洲欧美高清| 亚洲福利久久| 欧美成人一区二免费视频软件| 国产乱色国产精品免费视频| 丝袜美腿高跟呻吟高潮一区| 一区二区三区中文在线| 亚洲国产成人午夜在线一区| 正在播放亚洲一区| 在线观看亚洲精品视频| 亚洲色图自拍| 亚洲亚洲精品三区日韩精品在线视频| 成人一区二区三区视频在线观看| 日韩和欧美的一区| 亚洲色图欧美激情| 精品国产髙清在线看国产毛片| 欧美综合一区二区| 亚洲欧美日本视频在线观看| 国产精品国产一区二区| 99久久综合狠狠综合久久| 激情综合亚洲精品| 免费精品视频在线| 午夜激情久久久| 亚洲国产aⅴ成人精品无吗| 一区免费观看视频| 国产日韩av一区二区| 久久综合网色—综合色88| 日韩欧美区一区二| 欧美日韩国产免费| 欧美亚男人的天堂| 老牛国产精品一区的观看方式| 国产精品免费区二区三区观看| 狠狠爱www人成狠狠爱综合网| 91美女片黄在线| 91在线观看地址| 成人精品电影在线观看| 国产伦精品一区二区三区免费迷| 蜜桃久久久久久| 日韩福利视频导航| 毛片一区二区三区| 伊人色综合久久天天| 中文字幕在线一区| 国产精品免费免费| 久久网这里都是精品| 日韩一级黄色大片| 91精品国产综合久久久久久久 | 亚洲精品日产精品乱码不卡| 亚洲人精品一区| 国产精品色一区二区三区| 欧美国产日韩在线观看| 国产精品视频一二三区 | 欧美一区二区三区色| 91精品久久久久久久91蜜桃 | 午夜亚洲精品| 色哟哟在线观看一区二区三区| 六月婷婷一区| 久久久久久色| 一本色道亚洲精品aⅴ| 欧美色综合久久| 欧美一区二区三区公司| 精品国产三级a在线观看| 国产亚洲欧美激情| 国产精品不卡一区二区三区| 亚洲欧美偷拍三级| 亚洲图片欧美视频| 欧美96一区二区免费视频| 日本美女视频一区二区| 久久99热狠狠色一区二区| 国产风韵犹存在线视精品| 成人黄色大片在线观看| 欧美不卡三区| 99精品视频免费观看视频| 久久一二三四| 欧美久久久久久蜜桃|