最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

通俗易懂學(xué)習(xí)java并發(fā)工具類-Semaphore,Exchanger

 更新時間:2019年06月04日 08:38:56   作者:你聽___  
這篇文章主要介紹了java并發(fā)工具類-Semaphore,Exchanger,java并發(fā)工具類有很多,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,下面小編帶大家來一起學(xué)習(xí)一下吧

1. 控制資源并發(fā)訪問--Semaphore

Semaphore可以理解為信號量,用于控制資源能夠被并發(fā)訪問的線程數(shù)量,以保證多個線程能夠合理的使用特定資源。

Semaphore就相當(dāng)于一個許可證,線程需要先通過acquire方法獲取該許可證,該線程才能繼續(xù)往下執(zhí)行,否則只能在該方法出阻塞等待。當(dāng)執(zhí)行完業(yè)務(wù)功能后,需要通過release()方法將許可證歸還,以便其他線程能夠獲得許可證繼續(xù)執(zhí)行。

Semaphore可以用于做流量控制,特別是公共資源有限的應(yīng)用場景,比如數(shù)據(jù)庫連接。假如有多個線程讀取數(shù)據(jù)后,需要將數(shù)據(jù)保存在數(shù)據(jù)庫中,而可用的最大數(shù)據(jù)庫連接只有10個,這時候就需要使用Semaphore來控制能夠并發(fā)訪問到數(shù)據(jù)庫連接資源的線程個數(shù)最多只有10個。在限制資源使用的應(yīng)用場景下,Semaphore是特別合適的。

下面來看下Semaphore的主要方法:

//獲取許可,如果無法獲取到,則阻塞等待直至能夠獲取為止
void acquire() throws InterruptedException
//同acquire方法功能基本一樣,只不過該方法可以一次獲取多個許可
void acquire(int permits) throws InterruptedException
//釋放許可
void release()
//釋放指定個數(shù)的許可
void release(int permits)
//嘗試獲取許可,如果能夠獲取成功則立即返回true,否則,則返回false
boolean tryAcquire()
//與tryAcquire方法一致,只不過這里可以指定獲取多個許可
boolean tryAcquire(int permits)
//嘗試獲取許可,如果能夠立即獲取到或者在指定時間內(nèi)能夠獲取到,則返回true,否則返回false
boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException
//與上一個方法一致,只不過這里能夠獲取多個許可
boolean tryAcquire(int permits, long timeout, TimeUnit unit)
//返回當(dāng)前可用的許可證個數(shù)
int availablePermits()
//返回正在等待獲取許可證的線程數(shù)
int getQueueLength()
//是否有線程正在等待獲取許可證
boolean hasQueuedThreads()
//獲取所有正在等待許可的線程集合
Collection<Thread> getQueuedThreads()


另外,在Semaphore的構(gòu)造方法中還支持指定是夠具有公平性,默認(rèn)的是非公平性,這樣也是為了保證吞吐量。

一個例子

下面用一個簡單的例子來說明Semaphore的具體使用。我們來模擬這樣一樣場景。有一天,班主任需要班上10個同學(xué)到講臺上來填寫一個表格,但是老師只準(zhǔn)備了5支筆,因此,只能保證同時只有5個同學(xué)能夠拿到筆并填寫表格,沒有獲取到筆的同學(xué)只能夠等前面的同學(xué)用完之后,才能拿到筆去填寫表格。該示例代碼如下:

public class SemaphoreDemo {
//表示老師只有10支筆
private static Semaphore semaphore = new Semaphore(5);
public static void main(String[] args) {
//表示50個學(xué)生
ExecutorService service = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
service.execute(() -> {
try {
System.out.println(Thread.currentThread().getName() + " 同學(xué)準(zhǔn)備獲取筆......");
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " 同學(xué)獲取到筆");
System.out.println(Thread.currentThread().getName() + " 填寫表格ing.....");
TimeUnit.SECONDS.sleep(3);
semaphore.release();
System.out.println(Thread.currentThread().getName() + " 填寫完表格,歸還了筆!?。。。?!");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
service.shutdown();
}
}

輸出結(jié)果:

pool-1-thread-1 同學(xué)準(zhǔn)備獲取筆......
pool-1-thread-1 同學(xué)獲取到筆
pool-1-thread-1 填寫表格ing.....
pool-1-thread-2 同學(xué)準(zhǔn)備獲取筆......
pool-1-thread-2 同學(xué)獲取到筆
pool-1-thread-2 填寫表格ing.....
pool-1-thread-3 同學(xué)準(zhǔn)備獲取筆......
pool-1-thread-4 同學(xué)準(zhǔn)備獲取筆......
pool-1-thread-3 同學(xué)獲取到筆
pool-1-thread-4 同學(xué)獲取到筆
pool-1-thread-4 填寫表格ing.....
pool-1-thread-3 填寫表格ing.....
pool-1-thread-5 同學(xué)準(zhǔn)備獲取筆......
pool-1-thread-5 同學(xué)獲取到筆
pool-1-thread-5 填寫表格ing.....
pool-1-thread-6 同學(xué)準(zhǔn)備獲取筆......
pool-1-thread-7 同學(xué)準(zhǔn)備獲取筆......
pool-1-thread-8 同學(xué)準(zhǔn)備獲取筆......
pool-1-thread-9 同學(xué)準(zhǔn)備獲取筆......
pool-1-thread-10 同學(xué)準(zhǔn)備獲取筆......
pool-1-thread-4 填寫完表格,歸還了筆?。。。。?!
pool-1-thread-9 同學(xué)獲取到筆
pool-1-thread-9 填寫表格ing.....
pool-1-thread-5 填寫完表格,歸還了筆!?。。。?!
pool-1-thread-7 同學(xué)獲取到筆
pool-1-thread-7 填寫表格ing.....
pool-1-thread-8 同學(xué)獲取到筆
pool-1-thread-8 填寫表格ing.....
pool-1-thread-1 填寫完表格,歸還了筆?。。。。。?
pool-1-thread-6 同學(xué)獲取到筆
pool-1-thread-6 填寫表格ing.....
pool-1-thread-3 填寫完表格,歸還了筆!?。。。?!
pool-1-thread-2 填寫完表格,歸還了筆!?。。。?!
pool-1-thread-10 同學(xué)獲取到筆
pool-1-thread-10 填寫表格ing.....
pool-1-thread-7 填寫完表格,歸還了筆?。。。。?!
pool-1-thread-9 填寫完表格,歸還了筆?。。。。?!
pool-1-thread-8 填寫完表格,歸還了筆?。。。。?!
pool-1-thread-6 填寫完表格,歸還了筆?。。。。?!
pool-1-thread-10 填寫完表格,歸還了筆?。。。。。?

根據(jù)輸出結(jié)果進行分析,Semaphore允許的最大許可數(shù)為5,也就是允許的最大并發(fā)執(zhí)行的線程個數(shù)為5,可以看出,前5個線程(前5個學(xué)生)先獲取到筆,然后填寫表格,而6-10這5個線程,由于獲取不到許可,只能阻塞等待。

當(dāng)線程pool-1-thread-4釋放了許可之后,pool-1-thread-9就可以獲取到許可,繼續(xù)往下執(zhí)行。對其他線程的執(zhí)行過程,也是同樣的道理。

從這個例子就可以看出,Semaphore用來做特殊資源的并發(fā)訪問控制是相當(dāng)合適的,如果有業(yè)務(wù)場景需要進行流量控制,可以優(yōu)先考慮Semaphore。

2.線程間交換數(shù)據(jù)的工具--Exchanger

Exchanger是一個用于線程間協(xié)作的工具類,用于兩個線程間能夠交換。它提供了一個交換的同步點,在這個同步點兩個線程能夠交換數(shù)據(jù)。

具體交換數(shù)據(jù)是通過exchange方法來實現(xiàn)的,如果一個線程先執(zhí)行exchange方法,那么它會同步等待另一個線程也執(zhí)行exchange方法,這個時候兩個線程就都達到了同步點,兩個線程就可以交換數(shù)據(jù)。

Exchanger除了一個無參的構(gòu)造方法外,主要方法也很簡單:

//當(dāng)一個線程執(zhí)行該方法的時候,會等待另一個線程也執(zhí)行該方法,因此兩個線程就都達到了同步點
//將數(shù)據(jù)交換給另一個線程,同時返回獲取的數(shù)據(jù)
V exchange(V x) throws InterruptedException
//同上一個方法功能基本一樣,只不過這個方法同步等待的時候,增加了超時時間
V exchange(V x, long timeout, TimeUnit unit)
throws InterruptedException, TimeoutException 

一個例子

Exchanger理解起來很容易,這里用一個簡單的例子來看下它的具體使用。我們來模擬這樣一個情景,在青春洋溢的中學(xué)時代,下課期間,男生經(jīng)常會給走廊里為自己喜歡的女孩子送情書,相信大家都做過這樣的事情吧 :)。男孩會先到女孩教室門口,然后等女孩出來,教室那里就是一個同步點,然后彼此交換信物,也就是彼此交換了數(shù)據(jù)?,F(xiàn)在,就來模擬這個情景。

public class ExchangerDemo {
private static Exchanger<String> exchanger = new Exchanger();
public static void main(String[] args) {
//代表男生和女生
ExecutorService service = Executors.newFixedThreadPool(2);
service.execute(() -> {
try {
//男生對女生說的話
String girl = exchanger.exchange("我其實暗戀你很久了......");
System.out.println("女孩兒說:" + girl);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
service.execute(() -> {
try {
System.out.println("女生慢慢的從教室你走出來......");
TimeUnit.SECONDS.sleep(3);
//男生對女生說的話
String boy = exchanger.exchange("我也很喜歡你......");
System.out.println("男孩兒說:" + boy);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}

輸出結(jié)果:

女生慢慢的從教室你走出來......
男孩兒說:我其實暗戀你很久了......
女孩兒說:我也很喜歡你......

這個例子很簡單,也很能說明Exchanger的基本使用。當(dāng)兩個線程都到達調(diào)用exchange方法的同步點的時候,兩個線程就能交換彼此的數(shù)據(jù)。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring?MVC數(shù)據(jù)綁定方式

    Spring?MVC數(shù)據(jù)綁定方式

    這篇文章主要介紹了Spring?MVC數(shù)據(jù)綁定方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • java循環(huán)結(jié)構(gòu)、數(shù)組的使用小結(jié)

    java循環(huán)結(jié)構(gòu)、數(shù)組的使用小結(jié)

    這篇文章主要介紹了java循環(huán)結(jié)構(gòu)、數(shù)組的使用小結(jié),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • 簡單談?wù)凧ava中的棧和堆

    簡單談?wù)凧ava中的棧和堆

    堆和棧都是Java用來在RAM中存放數(shù)據(jù)的地方,下面這篇文章主要給大家介紹了關(guān)于Java中棧和堆的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-11-11
  • Java游戲服務(wù)器之?dāng)?shù)據(jù)庫表存取封裝

    Java游戲服務(wù)器之?dāng)?shù)據(jù)庫表存取封裝

    這篇文章主要介紹了Java游戲服務(wù)器之?dāng)?shù)據(jù)庫表存取封裝的相關(guān)資料,需要的朋友可以參考下
    2015-11-11
  • Spring-boot集成pg、mongo多數(shù)據(jù)源過程詳解

    Spring-boot集成pg、mongo多數(shù)據(jù)源過程詳解

    這篇文章主要介紹了Spring-boot集成pg、mongo多數(shù)據(jù)源過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • Java使用Scanner類進行控制臺輸入實現(xiàn)方法

    Java使用Scanner類進行控制臺輸入實現(xiàn)方法

    這篇文章主要介紹了Java使用Scanner類進行控制臺輸入實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Java數(shù)據(jù)類型轉(zhuǎn)換詳解

    Java數(shù)據(jù)類型轉(zhuǎn)換詳解

    這篇文章主要講解Java中基本數(shù)據(jù)類型、字符串與其它數(shù)據(jù)類型以及常見的日期類型的轉(zhuǎn)換,希望能給大家做一個參考。
    2016-06-06
  • SpringBoot整合Swagger2的示例

    SpringBoot整合Swagger2的示例

    這篇文章主要介紹了SpringBoot整合Swagger2的示例,幫助大家更好的理解和學(xué)習(xí)springboot框架,感興趣的朋友可以了解下
    2020-11-11
  • Java打包ZIP文件的使用

    Java打包ZIP文件的使用

    本文詳細(xì)介紹了如何使用Java語言進行ZIP文件的創(chuàng)建、讀取和操作,通過java.util.zip包和第三方庫,可以高效地處理ZIP文件,并應(yīng)用密碼保護和注釋等高級功能,在實際應(yīng)用中,遵循最佳實踐可以提高程序的健壯性和安全性
    2025-02-02
  • 一篇文章教你用Java使用JVM工具檢測問題

    一篇文章教你用Java使用JVM工具檢測問題

    這篇文章主要介紹了深入理解Java使用JVM工具檢測問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09

最新評論

绥化市| 泗阳县| 邹平县| 磐石市| 岳普湖县| 云安县| 武鸣县| 榕江县| 五河县| 枣庄市| 永兴县| 长治市| 泽州县| 城固县| 巴马| 广昌县| 军事| 诏安县| 安岳县| 屯昌县| 科尔| 宣武区| 美姑县| 兴隆县| 大安市| 东海县| 定南县| 平和县| 武胜县| 郑州市| 时尚| 万全县| 临洮县| 岳池县| 夏津县| 高要市| 加查县| 安康市| 独山县| 鄂伦春自治旗| 琼结县|