」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用信號量管理 Java 並發的技術

使用信號量管理 Java 並發的技術

發佈於2024-11-09
瀏覽:616

1. Java中的信号量是什么?

Techniques for Managing Concurrency in Java Using Semaphores

Java 中的信号量是一种同步辅助工具,它限制在任何给定时间可以访问共享资源的线程数量。它是 java.util.concurrent 包的一部分,用于管理对资源(例如文件、数据库或网络连接)的并发访问。

1.1 信号量如何工作?

Techniques for Managing Concurrency in Java Using Semaphores

信号量控制对一定数量的许可的访问。每个许可证代表访问特定资源的权利。信号量跟踪可用许可的数量,这决定了有多少线程可以同时访问资源。

Permit :允许线程继续访问共享资源的令牌或票证。

当您创建信号量时,您指定可用的许可证数量。该数字定义了有多少线程可以同时访问资源。

在线程可以访问资源之前,它必须从信号量获得许可。这是使用 acquire() 方法完成的。

Acquire :当线程想要访问资源时调用此方法。如果许可证可用,则信号量会减少可用许可证的数量并允许线程继续进行。如果没有可用的许可,则该线程将被阻塞,直到有可用的许可为止。

阻塞行为:如果没有可用的许可,调用 acquire() 的线程将被阻塞(即,它将等待),直到另一个线程释放许可。

一旦线程使用完资源,它应该释放许可证以使其可供其他线程使用。这是使用 release() 方法完成的。

Release :此方法会增加可用许可证的数量。如果有任何线程正在等待许可,则其中一个线程将被解除阻塞并允许获取许可。

1.2 信号量的类型

Java中有两种类型的信号量:

  • 计数信号量:这种类型的信号量允许一定数量的线程访问资源。例如,如果将信号量设置为3,则只有三个线程可以同时访问该资源。
  • 二进制信号量(互斥):这是计数信号量的一种特殊情况,其中许可数为 1,一次只允许一个线程访问资源。它经常被用作互斥锁(mutex)。

2. Java中信号量的实现

为了更好地理解信号量的工作原理,让我们看一下实际的实现。我们将创建一个简单的场景,其中多个线程尝试访问有限的资源。

2.1 搭建环境

import java.util.concurrent.Semaphore;

public class SemaphoreDemo {

    // Creating a semaphore with 3 permits
    private static final Semaphore semaphore = new Semaphore(3);

    public static void main(String[] args) {
        // Creating and starting 6 threads
        for (int i = 1; i 



2.2 代码解释

在此示例中,我们创建了一个具有三个许可的信号量,这意味着在任何给定时间只有三个线程可以访问代码的关键部分。然后我们创建六个线程,所有线程都尝试获取许可。一旦线程获得许可,它就会在释放许可之前通过休眠两秒钟来模拟某些工作。

2.3 观察输出

当您运行上面的代码时,输​​出将如下所示:

Worker 1 is trying to acquire a permit...
Worker 1 acquired a permit.
Worker 2 is trying to acquire a permit...
Worker 2 acquired a permit.
Worker 3 is trying to acquire a permit...
Worker 3 acquired a permit.
Worker 4 is trying to acquire a permit...
Worker 5 is trying to acquire a permit...
Worker 6 is trying to acquire a permit...
Worker 1 is releasing a permit.
Worker 4 acquired a permit.
Worker 2 is releasing a permit.
Worker 5 acquired a permit.
Worker 3 is releasing a permit.
Worker 6 acquired a permit.

这里,前三个线程成功获取许可并开始执行任务。其余线程必须等待许可证被释放后才能继续。

2.4 实际用例

信号量在需要限制特定资源并发访问数量的场景中特别有用,例如:

  • 限制数据库连接
  • 控制对共享文件的访问
  • 管理服务器中的网络连接

3. 使用信号量的优点和缺点

虽然信号量是一种强大的工具,但它们也有自己的优点和缺点。

3.1 优点

灵活性:信号量允许精确控制多个线程的资源访问。

可扩展性:信号量可以轻松管理对大量资源的访问。

公平性 :可以配置信号量以确保线程以公平的方式获取许可。

3.2 缺点

复杂性 :使用信号量会给代码带来复杂性,使调试变得更加困难。

死锁:如果处理不当,信号量可能会导致死锁,线程无限期地阻塞等待许可。

4. 在 Java 中使用信号量的最佳实践

为了避免常见陷阱并充分利用信号量,请考虑以下最佳实践:

4.1 使用tryAcquire进行限时获取

您可以使用 tryAcquire() 来尝试获取超时许可,而不是使用无限期阻塞的 acquire() 。这可以防止线程陷入等待状态。

if(semaphore.tryAcquire(1000, TimeUnit.MILLISECONDS)) {
    try {
        // Critical section
    } finally {
        semaphore.release();
    }
}

4.2 始终在finally块中释放许可

为了避免资源泄漏,请始终在 finally 块中释放许可证。这确保即使发生异常也能释放许可证。

4.3 避免使用信号量进行简单锁

如果您只需要为单个线程锁定和解锁资源,请考虑使用ReentrantLock或synchronized而不是二进制信号量。

5. 结论

信号量是 Java 中管理并发的强大工具,允许您控制访问共享资源的线程数量。通过遵循本文中概述的技术和最佳实践,您可以在 Java 应用程序中有效地实现信号量,以确保安全高效的资源管理。

如果您有任何疑问或想分享您自己的信号量经验,请随时在下面发表评论!

阅读更多帖子:使用信号量在 Java 中管理并发的技术

版本聲明 本文轉載於:https://dev.to/anh_trntun_4732cf3d299/techniques-for-managing-concurrency-in-java-using-semaphores-5ai?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何使用PHP將斑點(圖像)正確插入MySQL?
    如何使用PHP將斑點(圖像)正確插入MySQL?
    essue VALUES('$this->image_id','file_get_contents($tmp_image)')";This code builds a string in PHP, but the function call fil...
    程式設計 發佈於2025-03-25
  • 如何將PANDAS DataFrame列轉換為DateTime格式並按日期過濾?
    如何將PANDAS DataFrame列轉換為DateTime格式並按日期過濾?
    Transform Pandas DataFrame Column to DateTime FormatScenario:Data within a Pandas DataFrame often exists in various formats, including strings.使用時間數據時...
    程式設計 發佈於2025-03-25
  • 如何使用Depimal.parse()中的指數表示法中的數字?
    如何使用Depimal.parse()中的指數表示法中的數字?
    在嘗試使用Decimal.parse(“ 1.2345e-02”中的指數符號表示法表示的字符串時,您可能會遇到錯誤。這是因為默認解析方法無法識別指數符號。 成功解析這樣的字符串,您需要明確指定它代表浮點數。您可以使用numbersTyles.Float樣式進行此操作,如下所示:[&& && && ...
    程式設計 發佈於2025-03-25
  • 為什麼我的Makefile插值插圖不在$((())中?
    為什麼我的Makefile插值插圖不在$((())中?
    在嘗試在makefile命令中插值時,它仍然不適合。當將表達式封閉在雙捲髮括號中$(())中時,會發生這種情況。 解決此問題,將美元符號($)倍加倍。這有效地逃脫了第一個美元符號,允許正確的插值。 這是更正的makefile的示例: test:test: 進行測試$$(GO列表。/......
    程式設計 發佈於2025-03-25
  • 如何在其容器中為DIV創建平滑的左右CSS動畫?
    如何在其容器中為DIV創建平滑的左右CSS動畫?
    通用CSS動畫,用於左右運動 ,我們將探索創建一個通用的CSS動畫,以向左和右移動DIV,從而到達其容器的邊緣。該動畫可以應用於具有絕對定位的任何div,無論其未知長度如何。 問題:使用左直接導致瞬時消失 更加流暢的解決方案:混合轉換和左 [並實現平穩的,線性的運動,我們介紹了線性的轉換。...
    程式設計 發佈於2025-03-25
  • 如何同步迭代並從PHP中的兩個等級陣列打印值?
    如何同步迭代並從PHP中的兩個等級陣列打印值?
    同步的迭代和打印值來自相同大小的兩個數組使用兩個數組相等大小的selectbox時,一個包含country代碼的數組,另一個包含鄉村代碼,另一個包含其相應名稱的數組,可能會因不當提供了exply for for for the uncore for the forsion for for ytry...
    程式設計 發佈於2025-03-25
  • 如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    postgresql:為每個唯一標識符在postgresql中提取最後一行,您可能需要遇到與數據集合中每個不同標識的信息相關的信息。考慮以下數據:[ 1 2014-02-01 kjkj 在數據集中的每個唯一ID中檢索最後一行的信息,您可以在操作員上使用Postgres的有效效率: id dat...
    程式設計 發佈於2025-03-25
  • 如何有效地選擇熊貓數據框中的列?
    如何有效地選擇熊貓數據框中的列?
    在處理數據操作任務時,在Pandas DataFrames 中選擇列時,選擇特定列的必要條件是必要的。在Pandas中,選擇列的各種選項。 選項1:使用列名 如果已知列索引,請使用ILOC函數選擇它們。請注意,python索引基於零。 df1 = df.iloc [:,0:2]#使用索引0和1 ...
    程式設計 發佈於2025-03-25
  • 如何檢查對像是否具有Python中的特定屬性?
    如何檢查對像是否具有Python中的特定屬性?
    方法來確定對象屬性存在尋求一種方法來驗證對像中特定屬性的存在。考慮以下示例,其中嘗試訪問不確定屬性會引起錯誤: >>> a = someClass() >>> A.property Trackback(最近的最新電話): 文件“ ”,第1行, attributeError:SomeClass實...
    程式設計 發佈於2025-03-25
  • 如何在Java字符串中有效替換多個子字符串?
    如何在Java字符串中有效替換多個子字符串?
    在java 中有效地替換多個substring,需要在需要替換一個字符串中的多個substring的情況下,很容易求助於重複應用字符串的刺激力量。 However, this can be inefficient for large strings or when working with nu...
    程式設計 發佈於2025-03-25
  • 什麼是男式操作員(^)?
    什麼是男式操作員(^)?
    在Python [&&& && && && && && && &&華 11 [&& && && && && &&華 0011#3(二進制) ----#應用XOR('垂直') 1011#result = 11(binary)[&&&&&&& &&&&&&&&&&&&&&&&&&&&...
    程式設計 發佈於2025-03-25
  • 如何使用“ JSON”軟件包解析JSON陣列?
    如何使用“ JSON”軟件包解析JSON陣列?
    parsing JSON與JSON軟件包 QUALDALS:考慮以下go代碼:字符串 } func main(){ datajson:=`[“ 1”,“ 2”,“ 3”]`` arr:= jsontype {} 摘要:= = json.unmarshal([] byte(...
    程式設計 發佈於2025-03-25
  • 如何將多種用戶類型(學生,老師和管理員)重定向到Firebase應用中的各自活動?
    如何將多種用戶類型(學生,老師和管理員)重定向到Firebase應用中的各自活動?
    Red: How to Redirect Multiple User Types to Respective ActivitiesUnderstanding the ProblemIn a Firebase-based voting app with three distinct user type...
    程式設計 發佈於2025-03-25
  • 在細胞編輯後,如何維護自定義的JTable細胞渲染?
    在細胞編輯後,如何維護自定義的JTable細胞渲染?
    在JTable中維護jtable單元格渲染後,在JTable中,在JTable中實現自定義單元格渲染和編輯功能可以增強用戶體驗。但是,至關重要的是要確保即使在編輯操作後也保留所需的格式。 在設置用於格式化“價格”列的“價格”列,用戶遇到的數字格式丟失的“價格”列的“價格”之後,問題在設置自定義單元...
    程式設計 發佈於2025-03-25
  • 如何在鼠標單擊時編程選擇DIV中的所有文本?
    如何在鼠標單擊時編程選擇DIV中的所有文本?
    在鼠標上選擇div文本單擊帶有文本內容,用戶如何使用單個鼠標單擊單擊div中的整個文本?這允許用戶輕鬆拖放所選的文本或直接複製它。 在單個鼠標上單擊的div元素中選擇文本,您可以使用以下Javascript函數: function selecttext(canduterid){ if(d...
    程式設計 發佈於2025-03-25

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3