欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

如下圖所示:

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

1、Semaphore類

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

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

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

2、基本概念

2.1、信號(hào)量

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

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

信號(hào)量的計(jì)數(shù)器可以被設(shè)置為一個(gè)初始值,該值表示許可的數(shù)量。每當(dāng)一個(gè)線程獲取許可時(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è)線程以模擬數(shù)據(jù)庫連接
        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ù)庫操作
        } 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);
}

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

2.獲取連接

semaphore.acquire();

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

3.釋放連接

semaphore.release();

訪問完成后,線程釋放許可,讓其他線程能夠訪問。

多線程模擬

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

3、使用場(chǎng)景

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

4、死鎖

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

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

4.1、條件

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

4.2、解決策略

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

4.3、聯(lián)系

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

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

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

總結(jié)

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

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

相關(guān)文章

  • java?線程池存在的意義

    java?線程池存在的意義

    這篇文章主要介紹了java線程池存在的意義,通過多線程案例模擬鎖的產(chǎn)生的情況展開對(duì)主題的詳細(xì)介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-06-06
  • 一文帶你學(xué)習(xí)Java中的線程

    一文帶你學(xué)習(xí)Java中的線程

    線程是系統(tǒng)調(diào)度的最小單元,一個(gè)進(jìn)程可以包含多個(gè)線程,線程是負(fù)責(zé)執(zhí)行二進(jìn)制指令的。本文將詳細(xì)給大家介紹一下Java中的線程,,需要的朋友可以參考下
    2023-05-05
  • SpringBoot 使用WebSocket功能(實(shí)現(xiàn)步驟)

    SpringBoot 使用WebSocket功能(實(shí)現(xiàn)步驟)

    本文通過詳細(xì)步驟介紹了SpringBoot 使用WebSocket功能,首先需要導(dǎo)入WebSocket坐標(biāo),編寫WebSocket配置類,用于注冊(cè)WebSocket的Bean,結(jié)合示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • idea中增強(qiáng)for循環(huán)提示unexpected token問題

    idea中增強(qiáng)for循環(huán)提示unexpected token問題

    這篇文章主要介紹了idea中增強(qiáng)for循環(huán)提示unexpected token問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Spring之spring-context-indexer依賴詳解

    Spring之spring-context-indexer依賴詳解

    這篇文章主要介紹了Spring之spring-context-indexer依賴詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Spring Shell打Jar包時(shí)常用小技巧

    Spring Shell打Jar包時(shí)常用小技巧

    這篇文章主要介紹了Spring Shell打Jar包時(shí)常用小技巧,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java基于字符界面的簡(jiǎn)易收銀臺(tái)

    Java基于字符界面的簡(jiǎn)易收銀臺(tái)

    這篇文章主要為大家詳細(xì)介紹了Java基于字符界面的簡(jiǎn)易收銀臺(tái),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Spring的@PropertySource注解源碼解析

    Spring的@PropertySource注解源碼解析

    這篇文章主要介紹了Spring的@PropertySource注解源碼解析,就以源碼時(shí)序圖的方式,直觀的感受下@PropertySource注解在Spring源碼層面的執(zhí)行流程,需要的朋友可以參考下
    2023-11-11
  • java實(shí)現(xiàn)字符串轉(zhuǎn)String數(shù)組的方法示例

    java實(shí)現(xiàn)字符串轉(zhuǎn)String數(shù)組的方法示例

    這篇文章主要介紹了java實(shí)現(xiàn)字符串轉(zhuǎn)String數(shù)組的方法,涉及java字符串的遍歷、分割、轉(zhuǎn)換等相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10
  • Java實(shí)現(xiàn)學(xué)生管理系統(tǒng)

    Java實(shí)現(xiàn)學(xué)生管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)學(xué)生管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01

最新評(píng)論