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

Java并發(fā)之Semaphore工具類r的全面解析

 更新時間:2024年02月01日 14:59:52   作者:程序員古德  
Semaphore 是 java.util.concurrent中非常有用的并發(fā)編程工具類,它通常被用于限制對某個資源或資源池的并發(fā)訪問數(shù)量,下面我們就來深入了解一下Semaphore的具體使用吧

內(nèi)容概要

Semaphore通過控制許可數(shù)量,實現(xiàn)了對并發(fā)線程數(shù)的精細管理,有效避免了資源競爭和過載問題,能顯著提升系統(tǒng)吞吐量和響應速度,同時,Semaphore還支持公平與非公平策略,具有更好的靈活性和適應性,滿足了不同業(yè)務場景的需求。

核心概念

Semaphorejava.util.concurrent中非常有用的并發(fā)編程工具類,它通常被用于限制對某個資源或資源池的并發(fā)訪問數(shù)量。舉個實際的例子:假設一個餐廳里只有 10 張桌子,在繁忙的用餐時段,很多顧客會同時來到餐廳,但餐廳的空間有限,不能同時容納所有顧客,這時,就需要一種機制來控制進入餐廳的顧客數(shù)量,確保餐廳不會過于擁擠。

Semaphore 就可以扮演這個控制者的角色,可以將 Semaphore 的許可數(shù)設置為 10,這代表著餐廳里最多可以有 10 組顧客同時用餐,每當有顧客進入餐廳并坐下時,Semaphore 的許可數(shù)就會減 1;每當有顧客用餐完畢離開時,Semaphore 的許可數(shù)就會加 1,如果所有桌子都坐滿了,后來的顧客就需要在門外等待,直到有桌子空出來。

在這種業(yè)務場景下,使用Semaphore 就可以有效地控制餐廳的擁擠程度,保證了顧客的用餐體驗。

具體來說,Semaphore 通常用于以下場景:

  • 限制并發(fā)訪問量:當一個系統(tǒng)或應用需要限制對某個共享資源(如數(shù)據(jù)庫連接、文件、網(wǎng)絡服務等)的并發(fā)訪問量時,Semaphore 可以用來控制同時訪問這些資源的線程數(shù),通過設置 Semaphore 的許可數(shù),可以確保不會有過多的線程同時訪問資源,從而防止資源過載或爭用條件導致的性能下降。
  • 實現(xiàn)線程同步:除了限制并發(fā)訪問量外,Semaphore 還可以用于協(xié)調(diào)多個線程的執(zhí)行順序,例如,在一個多線程程序中,如果某個操作需要多個線程按照特定的順序執(zhí)行,可以使用 Semaphore 來控制這些線程的執(zhí)行流程。
  • 資源池管理Semaphore 還可以用于管理資源池,例如連接池、線程池等,通過動態(tài)調(diào)整 Semaphore 的許可數(shù),可以根據(jù)系統(tǒng)的負載情況動態(tài)地增加或減少資源的使用量,從而提高系統(tǒng)的伸縮性和資源利用率。

Semaphore 是一種靈活的同步工具,它非常適合在信號量場景中控制對資源的訪問,能夠在多線程環(huán)境中提供細粒度的控制,幫助開發(fā)者有效地管理系統(tǒng)資源,比如,用來控制對數(shù)據(jù)庫連接、線程池資源或其他共享資源的并發(fā)訪問,從而避免資源爭用和系統(tǒng)過載,保證系統(tǒng)的穩(wěn)定性和性能。

代碼案例

下面是一個簡單的Java代碼示例,演示了如何使用Semaphore來限制對一組資源的并發(fā)訪問,如下代碼:

import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Semaphore;  
  
public class SemaphoreExample {  
  
    // 創(chuàng)建一個Semaphore,初始許可為3,表示資源池中最多有3個資源可用  
    private static final Semaphore semaphore = new Semaphore(3);  
  
    public static void main(String[] args) {  
        // 創(chuàng)建一個固定大小的線程池來模擬客戶端請求  
        ExecutorService executor = Executors.newFixedThreadPool(5);  
  
        // 提交10個任務到線程池,每個任務代表一個客戶端請求  
        for (int i = 0; i < 10; i++) {  
            executor.submit(() -> {  
                try {  
                    // 線程嘗試獲取許可  
                    semaphore.acquire();  
                    System.out.println("線程" + Thread.currentThread().getName() + "獲取到資源,開始處理...");  
  
                    // 模擬資源處理時間  
                    Thread.sleep((long) (Math.random() * 1000));  
  
                    System.out.println("線程" + Thread.currentThread().getName() + "處理完畢,釋放資源...");  
  
                    // 線程釋放許可  
                    semaphore.release();  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            });  
        }  
  
        // 關閉線程池  
        executor.shutdown();  
    }  
}

在上面代碼中,創(chuàng)建了一個Semaphore實例,初始許可設置為3,這意味著最多只能有3個線程同時訪問資源,然后創(chuàng)建了一個固定大小為5的線程池來模擬客戶端請求,提交了10個任務到線程池,每個任務都嘗試獲取Semaphore的許可,模擬資源的訪問。

當線程調(diào)用semaphore.acquire()時,它會嘗試獲取一個許可,如果許可可用,線程將繼續(xù)執(zhí)行;如果沒有許可可用,線程將被阻塞,直到有許可可用。當線程完成資源訪問后,它調(diào)用semaphore.release()來釋放許可,這樣其他等待的線程就可以獲取許可并訪問資源了。

如下輸出結(jié)果:

線程pool-1-thread-1獲取到資源,開始處理...  
線程pool-1-thread-2獲取到資源,開始處理...  
線程pool-1-thread-3獲取到資源,開始處理...  
線程pool-1-thread-3處理完畢,釋放資源...  
線程pool-1-thread-1處理完畢,釋放資源...  
線程pool-1-thread-4獲取到資源,開始處理...  
線程pool-1-thread-2處理完畢,釋放資源...  
線程pool-1-thread-5獲取到資源,開始處理...  
線程pool-1-thread-4處理完畢,釋放資源...  
線程pool-1-thread-5處理完畢,釋放資源...  
線程pool-1-thread-3獲取到資源,開始處理...  
線程pool-1-thread-3處理完畢,釋放資源...

從輸出中可以看到,盡管有一個大小為5的線程池,但Semaphore確保了同時訪問資源的線程數(shù)不超過3個,當線程處理完資源后,它會釋放許可,允許其他線程獲取許可并繼續(xù)執(zhí)行。

核心API

下面是 Semaphore 類中一些重要方法的解釋:

acquire()

此方法用于獲取一個許可,如果當前沒有可用的許可,則當前線程會被阻塞,直到有許可可用,這是 Semaphore 最基本的使用方式,用于控制對資源的訪問。

acquire(int permits)

這個方法允許一次性獲取多個許可,如果當前可用許可數(shù)量少于請求的數(shù)量,則線程會被阻塞,直到有足夠的許可可用。

acquireUninterruptibly()

acquireUninterruptibly()acquireUninterruptibly(int permits)這兩個方法與 acquire 類似,但區(qū)別在于它們不會響應中斷,即使其他線程中斷了正在等待的線程,這些線程也會繼續(xù)等待,直到獲得許可。

tryAcquire

tryAcquire()tryAcquire(int permits)這兩個方法嘗試獲取一個或多個許可,如果當前有可用的許可則立即返回 true,并且獲取成功;如果沒有可用許可則立即返回 false,線程不會被阻塞。

tryAcquire(long timeout, TimeUnit unit)

tryAcquire(long timeout, TimeUnit unit)和tryAcquire(int permits, long timeout, TimeUnit unit)這兩個方法嘗試在給定的時間內(nèi)獲取一個或多個許可,如果在指定的時間內(nèi)獲得了許可,則返回 true;否則,返回 false,如果線程在等待期間被中斷,那么這兩個方法都會拋出 InterruptedException。

release

release()此方法用于釋放一個許可,將其返回給 Semaphore,這樣其他等待的線程就可以獲取它,通常在完成對資源的訪問后調(diào)用此方法。

release(int permits)

release(int permits)這個方法允許一次性釋放多個許可。

availablePermits

availablePermits()這個方法返回當前 Semaphore 中可用的許可數(shù)量。

hasQueuedThreads()

檢查是否有任何線程正在等待獲取許可。

getQueueLength()

返回正在等待獲取許可的線程數(shù)。

drainPermits()

此方法返回并刪除當前所有可用的許可,主要用于一些特殊的場景,比如需要在某個時刻一次性消耗所有許可。

reducePermits(int reduction)

這個方法用于減少 Semaphore 中的可用許可數(shù)量,通常用于一些動態(tài)調(diào)整資源池大小的場景,需要注意的是,這個方法不會阻塞,如果減少后的許可數(shù)小于0,那么會拋出 IllegalArgumentException。

注意:Semaphore 并不保證獲取許可的公平性,即等待時間最長的線程不一定會優(yōu)先獲得許可。

核心總結(jié)

優(yōu)點

  • 簡單易用:通過許可數(shù)量,輕松控制并發(fā)線程數(shù)。
  • 高效:避免了不必要的線程創(chuàng)建和銷毀,提高了系統(tǒng)吞吐量。
  • 靈活:支持公平和非公平策略,可根據(jù)需求選擇。

缺點

  • 不保證公平性:默認策略下,先到的線程不一定先獲得許可。
  • 可能導致死鎖:使用不當(如在持有Semaphore時執(zhí)行其他阻塞操作)時,可能會引發(fā)死鎖。

以上就是Java并發(fā)之Semaphore工具類r的全面解析的詳細內(nèi)容,更多關于Java Semaphore的資料請關注腳本之家其它相關文章!

相關文章

  • Java和MySQL數(shù)據(jù)庫中關于小數(shù)的保存問題詳析

    Java和MySQL數(shù)據(jù)庫中關于小數(shù)的保存問題詳析

    在Java和MySQL中小數(shù)的精度可能會受到限制,如float類型的小數(shù)只能精確到6-7位,double類型也只能精確到15-16位,這篇文章主要給大家介紹了關于Java和MySQL數(shù)據(jù)庫中關于小數(shù)的保存問題,需要的朋友可以參考下
    2024-01-01
  • 手把手教你SpringBoot過濾器N種注冊方式

    手把手教你SpringBoot過濾器N種注冊方式

    這篇文章主要介紹了手把手教你SpringBoot過濾器N種注冊方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • 一文帶你學會規(guī)則引擎Drools的應用

    一文帶你學會規(guī)則引擎Drools的應用

    Drools?就是一個開源的業(yè)務規(guī)則引擎,可以很容易地與?spring?boot?應用程序集成,這篇文章就來和大家詳細聊聊Drools的具體應用,需要的可以參考一下
    2023-03-03
  • 用SpringBoot Admin監(jiān)控SpringBoot程序

    用SpringBoot Admin監(jiān)控SpringBoot程序

    這篇文章主要介紹了用SpringBoot Admin監(jiān)控SpringBoot程序,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-10-10
  • 對Java字符串與整形、浮點類型之間的相互轉(zhuǎn)換方法總結(jié)

    對Java字符串與整形、浮點類型之間的相互轉(zhuǎn)換方法總結(jié)

    今天小編就為大家分享一篇對Java字符串與整形、浮點類型之間的相互轉(zhuǎn)換方法總結(jié),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • 淺談Arrays.asList() 和ArrayList類型區(qū)別

    淺談Arrays.asList() 和ArrayList類型區(qū)別

    下面小編就為大家?guī)硪黄狝rrays.asList() 和ArrayList類型區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • java: 程序包com.fasterxml.jackson.annotation不存在的解決辦法

    java: 程序包com.fasterxml.jackson.annotation不存在的解決辦法

    當我們在導入程序之后,系統(tǒng)給出錯誤提示:java: 程序包com.fasterxml.jackson.annotation不存在,本文主要介紹了Java程序包不存在的三種解決方法,需要的朋友可以參考下
    2024-02-02
  • Maven的配置文件pom.xml詳解(含常用plugin)

    Maven的配置文件pom.xml詳解(含常用plugin)

    pom.xml是Maven項目的核心配置文件,它是 項目對象模型 - Project Object Model(POM)的縮寫,本文我們將全面解析pom.xml,了解其結(jié)構(gòu)和屬性,以及如何使用它來管理項目,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • Java模擬登錄正方教務抓取成績、課表、空教室

    Java模擬登錄正方教務抓取成績、課表、空教室

    這篇文章主要介紹了Java模擬登錄正方教務抓取成績、課表、空教室等信息,Java實現(xiàn)模擬登錄正方教務抓取成績、課表、空教室,通過HttpClient來模擬瀏覽器請求,Jsoup解析網(wǎng)頁內(nèi)容,感興趣的小伙伴們可以參考一下
    2016-04-04
  • SpringBoot的HTTPS配置實現(xiàn)

    SpringBoot的HTTPS配置實現(xiàn)

    本文主要介紹了SpringBoot的HTTPS配置實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04

最新評論