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

多線(xiàn)程并發(fā)控制工具Semaphore的使用詳解

 更新時(shí)間:2025年05月13日 10:27:48   作者:找不到、了  
這篇文章主要介紹了多線(xiàn)程并發(fā)控制工具Semaphore的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

當(dāng)在多線(xiàn)程運(yùn)行的場(chǎng)景,部分共享資源會(huì)存在資源的沖突和競(jìng)爭(zhēng),為了改善資源使用的方式,是否可以通過(guò)控制某個(gè)方法允許并發(fā)訪(fǎng)問(wèn)線(xiàn)程的數(shù)量?

如下圖所示:

Semaphore可以有效的緩解這個(gè)問(wèn)題。

1、Semaphore類(lèi)

在jdk中提供了一個(gè)Semaphore類(lèi)(信號(hào)量)

它提供了兩個(gè)方法:

  • semaphore.acquire() 請(qǐng)求信號(hào)量,可以限制線(xiàn)程的個(gè)數(shù),是一個(gè)正數(shù),如果信號(hào)量是-1,就代表已經(jīng)用完了信號(hào)量,其他線(xiàn)程需要阻塞了。
  • 第二個(gè)方法是semaphore.release(),代表是釋放一個(gè)信號(hào)量,此時(shí)信號(hào)量的個(gè)數(shù)+1。

2、基本概念

2.1、信號(hào)量

Semaphore 維護(hù)了一個(gè)計(jì)數(shù)器(許可的數(shù)量),表示可以同時(shí)訪(fǎng)問(wèn)某個(gè)資源的線(xiàn)程數(shù)量。線(xiàn)程通過(guò)申請(qǐng)?jiān)S可來(lái)訪(fǎng)問(wèn)資源。

2.2、計(jì)數(shù)器

信號(hào)量的計(jì)數(shù)器可以被設(shè)置為一個(gè)初始值,該值表示許可的數(shù)量。每當(dāng)一個(gè)線(xiàn)程獲取許可時(shí),計(jì)數(shù)器減一;當(dāng)釋放許可時(shí),計(jì)數(shù)器加一。

2.3、公平性

Semaphore 可以配置為公平或非公平。公平的信號(hào)量遵循 FIFO(先入先出)原則,非公平信號(hào)量則不保證獲取的順序。

代碼示例:

import java.util.concurrent.Semaphore;

public class SemaphoreTest {

    public static void main(String[] args) {
        final DatabaseConnectionPool pool = new DatabaseConnectionPool(3);

        // 創(chuàng)建多個(gè)線(xiàn)程以模擬數(shù)據(jù)庫(kù)連接
        Thread thread1 = new Thread(() -> pool.connect("Thread 1"));
        Thread thread2 = new Thread(() -> pool.connect("Thread 2"));
        Thread thread3 = new Thread(() -> pool.connect("Thread 3"));
        Thread thread4 = new Thread(() -> pool.connect("Thread 4"));
        Thread thread5 = new Thread(() -> pool.connect("Thread 5"));


        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
        thread5.start();

    }
}


class DatabaseConnectionPool{
    private final Semaphore semaphore;

    DatabaseConnectionPool(int maxConnections) {
        this.semaphore = new Semaphore(maxConnections,true);
    }

    public void connect(String threadName) {
        try {
            System.out.println(threadName + " is trying to connect.");
            // 獲取許可
            semaphore.acquire();
            System.out.println(threadName + " has connected to the database.");
            // 模擬使用連接
            Thread.sleep(5000); // 模擬數(shù)據(jù)庫(kù)操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            // 釋放許可
            System.out.println(threadName + " is releasing the connection.");
            semaphore.release();
        }
    }
}

代碼解析

1.Semaphore 的創(chuàng)建

public DatabaseConnectionPool(int maxConnections) {
    this.semaphore = new Semaphore(maxConnections);
}

通過(guò)指定最大連接數(shù)來(lái)初始化信號(hào)量。

2.獲取連接

semaphore.acquire();

線(xiàn)程嘗試獲取信號(hào)量的許可,如果沒(méi)有可用的許可,則該線(xiàn)程會(huì)被阻塞,直到有許可可用。

3.釋放連接

semaphore.release();

訪(fǎng)問(wèn)完成后,線(xiàn)程釋放許可,讓其他線(xiàn)程能夠訪(fǎng)問(wèn)。

多線(xiàn)程模擬

使用多個(gè)線(xiàn)程來(lái)模擬多個(gè)連接請(qǐng)求,只有 3 個(gè)線(xiàn)程能同時(shí)獲取許可。

3、使用場(chǎng)景

  • 控制并發(fā)訪(fǎng)問(wèn)某些資源,例如數(shù)據(jù)庫(kù)連接、文件句柄等。
  • 限制同時(shí)執(zhí)行的線(xiàn)程數(shù)量,以避免系統(tǒng)負(fù)載過(guò)大。

4、死鎖

死鎖是一種情況,其中兩個(gè)或多個(gè)線(xiàn)程永遠(yuǎn)互相等待對(duì)方釋放資源,從而導(dǎo)致程序無(wú)法繼續(xù)執(zhí)行。

了解更多死鎖知識(shí),可參考:有關(guān)Java死鎖和活鎖的聯(lián)系

4.1、條件

  1. 互斥條件:至少有一個(gè)資源處于非共享模式,即某一時(shí)刻只能被一個(gè)線(xiàn)程使用。
  2. 保持并等待條件:一個(gè)線(xiàn)程保持至少一個(gè)資源并等待其他被其他線(xiàn)程占用的資源。
  3. 不剝奪條件:資源不能被強(qiáng)行奪走,只能由持有該資源的線(xiàn)程釋放。
  4. 循環(huán)等待條件:存在一個(gè)線(xiàn)程的集合,使得每個(gè)線(xiàn)程都在等待下一個(gè)線(xiàn)程持有的資源。

4.2、解決策略

  • 資源順序申請(qǐng):確保所有線(xiàn)程按照相同的順序請(qǐng)求多個(gè)資源,這樣可以避免循環(huán)等待。
  • 設(shè)置超時(shí):在請(qǐng)求資源時(shí)設(shè)置超時(shí),如果請(qǐng)求在一定時(shí)間內(nèi)沒(méi)有成功,線(xiàn)程應(yīng)該釋放它已持有的資源,有可能中斷互斥條件。
  • 使用 tryLock tryAcquire:可使用 LockSemaphore 的嘗試獲取方法,在未能成功獲取時(shí),可以做適當(dāng)?shù)腻e(cuò)誤處理或重試,而不是靜默等待。
  • 避免持有狀態(tài):盡量避免在一個(gè)線(xiàn)程中持有多個(gè)鎖,或者隔離資源,以減少死鎖風(fēng)險(xiǎn)。

4.3、聯(lián)系

雖然 Semaphore 可以在某種情況下幫助減少發(fā)生死鎖的機(jī)會(huì),但它并不是解決死鎖問(wèn)題的直接手段。

Semaphore 控制訪(fǎng)問(wèn)的方式可以導(dǎo)致某些設(shè)計(jì)上的改善,例如:

  1. 限制資源的同時(shí)訪(fǎng)問(wèn)Semaphore 可用于限制可同時(shí)訪(fǎng)問(wèn)某種資源的線(xiàn)程數(shù)量,從而減少?gòu)?fù)雜的資源使用模式。
  2. 避免持有過(guò)多的鎖:通過(guò)合理設(shè)計(jì)線(xiàn)程的資源申請(qǐng)和釋放邏輯,結(jié)合 Semaphore,可以減少因線(xiàn)程在持有多個(gè)資源時(shí)發(fā)生互斥和等待的可能性。

總結(jié)

Semaphore 是一個(gè)非常有用的并發(fā)控制工具,可以有效地控制對(duì)共享資源的訪(fǎng)問(wèn)。通過(guò)合理使用它,可以避免過(guò)多線(xiàn)程同時(shí)訪(fǎng)問(wèn)相同資源造成的競(jìng)爭(zhēng)和沖突,從而提高并發(fā)程序的安全性和效率。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringCloud Feign遠(yuǎn)程調(diào)用實(shí)現(xiàn)詳解

    SpringCloud Feign遠(yuǎn)程調(diào)用實(shí)現(xiàn)詳解

    Feign是Netflix公司開(kāi)發(fā)的一個(gè)聲明式的REST調(diào)用客戶(hù)端; Ribbon負(fù)載均衡、 Hystrⅸ服務(wù)熔斷是我們Spring Cloud中進(jìn)行微服務(wù)開(kāi)發(fā)非?;A(chǔ)的組件,在使用的過(guò)程中我們也發(fā)現(xiàn)它們一般都是同時(shí)出現(xiàn)的,而且配置也都非常相似
    2022-11-11
  • IDEA插件之mybatisx?插件使用教程

    IDEA插件之mybatisx?插件使用教程

    這篇文章主要介紹了mybatisx?插件使用教程,包括插件安裝自動(dòng)生成代碼的相關(guān)知識(shí),本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • SpringBoot中優(yōu)化if-else語(yǔ)句的七種方法

    SpringBoot中優(yōu)化if-else語(yǔ)句的七種方法

    if-else語(yǔ)句是控制流程的基本工具,但過(guò)度使用會(huì)使代碼變得復(fù)雜且難以維護(hù),在SpringBoot , SpringCloud項(xiàng)目中,優(yōu)化if-else結(jié)構(gòu)變得尤為重要,本文將深入探討七種策略,旨在減少SpringBoot , SpringCloud項(xiàng)目中 if-else的使用,需要的朋友可以參考下
    2024-07-07
  • Spring?Boot?使用觀察者模式實(shí)現(xiàn)實(shí)時(shí)庫(kù)存管理的步驟

    Spring?Boot?使用觀察者模式實(shí)現(xiàn)實(shí)時(shí)庫(kù)存管理的步驟

    在現(xiàn)代軟件開(kāi)發(fā)中,實(shí)時(shí)數(shù)據(jù)處理非常關(guān)鍵,本文提供了一個(gè)使用SpringBoot和觀察者模式開(kāi)發(fā)實(shí)時(shí)庫(kù)存管理系統(tǒng)的詳細(xì)教程,步驟包括創(chuàng)建項(xiàng)目、定義實(shí)體類(lèi)、實(shí)現(xiàn)觀察者模式、集成Spring框架、創(chuàng)建RESTful?API端點(diǎn)和測(cè)試應(yīng)用等,這將有助于開(kāi)發(fā)者構(gòu)建能夠即時(shí)響應(yīng)庫(kù)存變化的系統(tǒng)
    2024-09-09
  • java聊天室的實(shí)現(xiàn)代碼

    java聊天室的實(shí)現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了java聊天室的實(shí)現(xiàn)代碼,一個(gè)多客戶(hù)端聊天室,支持多客戶(hù)端聊天,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • 分布式Netty源碼分析EventLoopGroup及介紹

    分布式Netty源碼分析EventLoopGroup及介紹

    這篇文章主要介紹了分布式Netty源碼分析EventLoopGroup及介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • alibaba?seata服務(wù)端具體實(shí)現(xiàn)

    alibaba?seata服務(wù)端具體實(shí)現(xiàn)

    seata是來(lái)處理分布式服務(wù)之間互相調(diào)用的事務(wù)問(wèn)題,本文重點(diǎn)給大家介紹alibaba-seata實(shí)現(xiàn)方法,文中通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • Java線(xiàn)程池用法實(shí)戰(zhàn)案例分析

    Java線(xiàn)程池用法實(shí)戰(zhàn)案例分析

    這篇文章主要介紹了Java線(xiàn)程池用法,結(jié)合具體案例形式分析了java線(xiàn)程池創(chuàng)建、使用、終止等相關(guān)操作技巧與使用注意事項(xiàng),需要的朋友可以參考下
    2019-10-10
  • 如何在Java中調(diào)用python文件執(zhí)行詳解

    如何在Java中調(diào)用python文件執(zhí)行詳解

    豐富的第三方庫(kù)使得python非常適合用于進(jìn)行數(shù)據(jù)分析,最近在項(xiàng)目中就涉及到j(luò)ava調(diào)用python實(shí)現(xiàn)的算法,下面這篇文章主要給大家介紹了關(guān)于如何在Java中調(diào)用python文件執(zhí)行的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • Spring內(nèi)置定時(shí)任務(wù)調(diào)度@Scheduled使用詳解

    Spring內(nèi)置定時(shí)任務(wù)調(diào)度@Scheduled使用詳解

    這篇文章主要介紹了Spring內(nèi)置定時(shí)任務(wù)調(diào)度@Scheduled使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12

最新評(píng)論

焉耆| 手游| 桃园县| 厦门市| 抚州市| 阿克| 北辰区| 齐齐哈尔市| 藁城市| 鞍山市| 宁远县| 德化县| 大田县| 新乐市| 伽师县| 务川| 榆社县| 诸暨市| 咸丰县| 宜良县| 山阳县| 广南县| 米脂县| 永德县| 普安县| 平乐县| 信丰县| 新民市| 始兴县| 定南县| 淮南市| 开鲁县| 津市市| 兖州市| 闽侯县| 长岭县| 伊宁县| 岳阳市| 阿克苏市| SHOW| 邛崃市|