91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用java并發工具Semaphore和Exchanger

發布時間:2021-10-13 13:40:52 來源:億速云 閱讀:137 作者:柒染 欄目:編程語言

這篇文章將為大家詳細講解有關如何使用java并發工具Semaphore和Exchanger,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

1. 控制資源并發訪問--Semaphore

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

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

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

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

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

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

一個例子

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

public class SemaphoreDemo {//表示老師只有10支筆private static Semaphore semaphore = new Semaphore(5);public static void main(String[] args) {//表示50個學生ExecutorService service = Executors.newFixedThreadPool(10);for (int i = 0; i < 10; i++) {service.execute(() -> {try {System.out.println(Thread.currentThread().getName() + " 同學準備獲取筆......");semaphore.acquire();System.out.println(Thread.currentThread().getName() + " 同學獲取到筆");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();}}

輸出結果:

pool-1-thread-1 同學準備獲取筆......pool-1-thread-1 同學獲取到筆pool-1-thread-1 填寫表格ing.....pool-1-thread-2 同學準備獲取筆......pool-1-thread-2 同學獲取到筆pool-1-thread-2 填寫表格ing.....pool-1-thread-3 同學準備獲取筆......pool-1-thread-4 同學準備獲取筆......pool-1-thread-3 同學獲取到筆pool-1-thread-4 同學獲取到筆pool-1-thread-4 填寫表格ing.....pool-1-thread-3 填寫表格ing.....pool-1-thread-5 同學準備獲取筆......pool-1-thread-5 同學獲取到筆pool-1-thread-5 填寫表格ing.....pool-1-thread-6 同學準備獲取筆......pool-1-thread-7 同學準備獲取筆......pool-1-thread-8 同學準備獲取筆......pool-1-thread-9 同學準備獲取筆......pool-1-thread-10 同學準備獲取筆......pool-1-thread-4 填寫完表格,歸還了筆!!!!!!pool-1-thread-9 同學獲取到筆pool-1-thread-9 填寫表格ing.....pool-1-thread-5 填寫完表格,歸還了筆!!!!!!pool-1-thread-7 同學獲取到筆pool-1-thread-7 填寫表格ing.....pool-1-thread-8 同學獲取到筆pool-1-thread-8 填寫表格ing.....pool-1-thread-1 填寫完表格,歸還了筆!!!!!!pool-1-thread-6 同學獲取到筆pool-1-thread-6 填寫表格ing.....pool-1-thread-3 填寫完表格,歸還了筆!!!!!!pool-1-thread-2 填寫完表格,歸還了筆!!!!!!pool-1-thread-10 同學獲取到筆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 填寫完表格,歸還了筆!!!!!!

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

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

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

2.線程間交換數據的工具--Exchanger

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

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

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

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

一個例子

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

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();}});}}

輸出結果:

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

這個例子很簡單,也很能說明Exchanger的基本使用。當兩個線程都到達調用exchange方法的同步點的時候,兩個線程就能交換彼此的數據。

關于如何使用java并發工具Semaphore和Exchanger就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

柳江县| 堆龙德庆县| 尚义县| 如皋市| 彰武县| 宽甸| 宜城市| 集贤县| 鲁甸县| 左权县| 平原县| 峨眉山市| 霍林郭勒市| 增城市| 米脂县| 丹巴县| 千阳县| 苍溪县| 河池市| 柘荣县| 芦溪县| 麻阳| 定安县| 黔江区| 横峰县| 勃利县| 三江| 廉江市| 涿鹿县| 望城县| 阿拉善左旗| 大宁县| 蕲春县| 固原市| 虹口区| 平顶山市| 尚义县| 正镶白旗| 万盛区| 化州市| 湘潭市|