Java 多線程工具類 Semaphore

引言

在多線程編程中,控制對共享資源的訪問是一個關鍵問題。Java 提供了多種同步機制來解決這個問題,其中 Semaphore 是一種常用的工具類,用于限制可以同時訪問某個資源的線程數。本文將詳細介紹 Semaphore 的概念、使用方法和實際應用場景。

1. Semaphore 概述

Semaphorejava.util.concurrent 包中的一個類,用于控制同時訪問某個特定資源的線程數量。它維護了一組許可(permits),線程在訪問資源前必須先獲得許可,訪問結束后再釋放許可。Semaphore 可以用于實現資源池、限流器等功能。

2. Semaphore 的基本使用

2.1 初始化

Semaphore 可以通過兩種方式進行初始化:

// 初始化一個具有指定許可數量的 Semaphore
Semaphore semaphore = new Semaphore(permits);// 初始化一個具有指定許可數量,并指定是否為公平模式的 Semaphore
Semaphore semaphore = new Semaphore(permits, fair);
  • permits:初始的許可數量。
  • fair:如果為 true,則 Semaphore 按照 FIFO(先進先出)原則分配許可,否則按照默認的非公平模式。
2.2 主要方法
  • acquire():獲取一個許可,如果沒有可用的許可,則阻塞直到有許可可用。
  • acquire(int permits):獲取指定數量的許可。
  • tryAcquire():嘗試獲取一個許可,立即返回,不阻塞。
  • tryAcquire(int permits):嘗試獲取指定數量的許可。
  • release():釋放一個許可。
  • release(int permits):釋放指定數量的許可。

3. 示例代碼

以下是一個使用 Semaphore 控制對共享資源訪問的示例代碼,模擬了一個停車場的場景,限制了同時停放的車輛數量。

import java.util.concurrent.Semaphore;public class ParkingLot {private final Semaphore semaphore;public ParkingLot(int slots) {this.semaphore = new Semaphore(slots);}public void parkCar(String carName) {try {System.out.println(carName + " is trying to enter the parking lot.");semaphore.acquire();System.out.println(carName + " has entered the parking lot.");// 模擬停車時間Thread.sleep((long) (Math.random() * 10000));} catch (InterruptedException e) {e.printStackTrace();} finally {System.out.println(carName + " is leaving the parking lot.");semaphore.release();}}public static void main(String[] args) {final int parkingSlots = 3;final ParkingLot parkingLot = new ParkingLot(parkingSlots);for (int i = 1; i <= 10; i++) {final String carName = "Car-" + i;new Thread(() -> parkingLot.parkCar(carName)).start();}}
}

4. Semaphore 的實際應用場景

  • 資源池:控制對有限資源的并發訪問,如數據庫連接池、線程池等。
  • 限流器:限制某些操作的并發執行數量,防止過載。
  • 多路復用器:實現多路復用機制,控制對多個資源的訪問。
  • 同步工具:協調多線程之間的交互,確保按順序訪問某些資源。

5. Semaphore 的優缺點

優點
  • 靈活性:可以靈活控制同時訪問資源的線程數量。
  • 簡單易用:API 簡單明了,容易理解和使用。
  • 公平性:支持公平模式,保證線程按順序獲取許可。
缺點
  • 性能開銷:在高并發場景下,頻繁的許可獲取和釋放操作可能帶來一定的性能開銷。
  • 死鎖風險:如果許可獲取和釋放操作不正確,可能導致死鎖。

6. Semaphore 的擴展

  • 超時機制tryAcquire(long timeout, TimeUnit unit) 方法可以嘗試在指定時間內獲取許可,如果超時則返回 false
  • 多許可控制Semaphore 可以同時控制多個許可,通過 acquire(int permits)release(int permits) 方法進行多許可的獲取和釋放。

結論

Semaphore 是 Java 并發包中一個強大的工具類,用于控制對共享資源的并發訪問。通過使用 Semaphore,可以方便地限制同時訪問某個資源的線程數量,從而實現資源池、限流器等功能。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/42742.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/42742.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/42742.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ARM GEC6818 LCD繪圖 實心圓 三角形 五角星 任意區域矩形以及旗幟

要在ARM上實現LCD繪圖,可以按照以下步驟進行: 硬件初始化:初始化LCD控制器和相關引腳,配置時鐘、分辨率和顏色深度等。 內存映射:將LCD顯示區域映射到ARM的內存地址空間中,可以通過ARM的內存映射機制來實現。 繪圖函數:實現繪制基本圖形的函數,如點、線、矩形、圓等。可…

【系統架構設計師】八、系統工程基礎知識(系統工程|系統性能)

目錄 一、系統工程 1.1 系統工程的方法 1.1.1 霍爾的三維結構 1.1.2 切克蘭德方法 1.1.3 并行工程方法 1.1.4 綜合集成法 1.1.5.WSR 系統方法。 二、系統工程生命周期 2.1 系統工程生命周期7階段 2.2 生命周期方法 三、基于模型的系統工程(MBSE) 四、系統性能 4.1…

vb.netcad二開自學筆記6:第一個繪制線段命令

.net編寫繪制直線已完全不同于ActiveX的&#xff08;VBA&#xff09;的方式&#xff0c;過程更類似于arx程序&#xff0c;需要通過操作AutoCAD 數據庫添加對象&#xff01;下面的代碼是在以前代碼基礎上添加了一個新myline命令。 AutoCAD 數據庫結構 myline命令代碼 Imports A…

YoloV9改進策略:Block改進|輕量實時的重參數結構|最新改進|即插即用(全網首發)

摘要 本文使用重參數的Block替換YoloV9中的RepNBottleneck&#xff0c;GFLOPs從239降到了227&#xff1b;同時&#xff0c;map50從0.989漲到了0.99&#xff08;重參數后的結果&#xff09;。 改進方法簡單&#xff0c;只做簡單的替換就行&#xff0c;即插即用&#xff0c;非常…

使用ndoe實現自動化完成增刪改查接口

使用ndoe實現自動化完成增刪改查接口 最近工作內容比較繁瑣&#xff0c;手里需要開發的項目需求比較多&#xff0c;常常在多個項目之間來回切換&#xff0c;有時候某些分支都不知道自己開發了什么、做了哪些需求&#xff0c; 使用手寫筆記的方式去記錄分支到頭來也是眼花繚亂&a…

vscode調試教程

VSCode調試 VSCode Debuggers VSCode使用launch.json進行細粒度的控制&#xff0c;可以啟動程序或將其附加到復雜的調試場景中 打開Run and Debug視圖Ctrl Shift D 點擊create a launch.json file&#xff0c;選擇C(GDB/LLDB) 會在工作目錄自動創建.vscode/launch.json文…

【MyBatis】MyBatis 理論 40 問(二)

《MyBatis 理論 40 問》包含以下 2 篇文章&#xff1a; MyBatis 理論 40 問&#xff08;一&#xff09;MyBatis 理論 40 問&#xff08;二&#xff09; MyBatis 理論 40 問&#xff08;二&#xff09; 21.如何獲取生成的主鍵&#xff1f;22.當實體類中的屬性名和表中的字段名不…

influxQL基本語法及常用的聚合函數

InfluxQL&#xff08;Influx Query Language&#xff09;是與InfluxDB緊密集成的一種SQL風格的語言&#xff0c;專為處理時間序列數據而設計。其基本語法結構清晰&#xff0c;方便開發者理解和實現。以下是對InfluxQL基本語法及常用聚合函數的簡單介紹&#xff1a; 目錄 一、…

Docker Dockerfile:構建與優化

Docker Dockerfile&#xff1a;構建與優化 簡介 Docker 是一種廣泛使用的容器化技術&#xff0c;它允許開發人員將應用程序及其依賴環境打包到一個可移植的容器中。Dockerfile 是 Docker 中用于自動化容器鏡像構建的腳本文件。本文將詳細介紹 Dockerfile 的基本結構、指令使用…

【Python】已解決:(MongoDB安裝報錯)‘mongo’ 不是內部或外部命令,也不是可運行的程序

文章目錄 一、分析問題背景二、可能出錯的原因三、錯誤代碼示例四、正確代碼示例及解決方案五、注意事項 已解決&#xff1a;&#xff08;MongoDB安裝報錯&#xff09;‘mongo’ 不是內部或外部命令,也不是可運行的程序 一、分析問題背景 在安裝和配置MongoDB時&#xff0c;有…

怎樣在 PostgreSQL 中優化對 UUID 數據類型的索引和查詢?

文章目錄 一、UUID 數據類型概述二、UUID 索引和查詢的性能問題三、優化方案&#xff08;一&#xff09;選擇合適的索引類型&#xff08;二&#xff09;壓縮 UUID&#xff08;三&#xff09;拆分 UUID&#xff08;四&#xff09;使用覆蓋索引&#xff08;五&#xff09;優化查詢…

一二三應用開發平臺應用開發示例(6)——代碼生成、權限配置、運行效果查看

生成代碼 完成配置工作&#xff0c;接下來就是見證奇跡的時刻~ 返回到實體列表&#xff0c;選中“文件夾”記錄&#xff0c;點擊“生成代碼”按鈕&#xff0c;提示成功后&#xff0c;在項目的output目錄下輸出了平臺基于配置模板產生的各層代碼&#xff0c;在原有后端的基礎上…

Pyserial設置緩沖區大小失敗

文章目錄 問題描述原因分析解決方案 問題描述 使用set_buffer_size()設置緩沖區大小后&#xff0c;buffer size仍為默認的4096 import time import serial ser serial.Serial(baudrate9600, timeout0.5) ser.port COM1 ser.set_buffer_size(rx_size8192) ser.open() while …

windows上部署python3.11

hello&#xff0c;大家好&#xff0c;我是一名測試開發工程師&#xff0c;至今已在自動化測試領域深耕9個年頭&#xff0c;現已將本人實戰多年的多終端自動化測試框架【wyTest】開源啦&#xff0c;在接下來的一個月里&#xff0c;我將免費指導大家使用wyTest&#xff0c;請大家…

歐拉函數.

性質1&#xff1a;質數n的歐拉函數為n-1. 性質2&#xff1a;如果p&#xff0c;q都是質數&#xff0c;那么? ( p ? q ) ? ( p ) ? ? ( q ) ( p ? 1 ) ? ( q ? 1 ) 證明&#xff1a;p&#xff0c;2p....q*p都不與q*p互質&#xff0c;q同理&#xff0c;所以總的不互質個…

JavaEE初階-網絡編程

文章目錄 前言一、UDP與TCP1.1 有連接與無連接1.2 全雙工1.3 可靠傳輸與不可靠傳輸1.4 面向子節流與面向數據報 二、UDP回顯服務器及客戶端編寫三、UDP字典服務器四、TCP回顯服務器及客戶端編寫五、數據序列化的方式5.1 基于行文本的方式傳輸5.2 基于XML的格式5.3 基于json5.4 …

STM32芯片系列與產品后綴解讀

一. 產品系列 STM32單片機是一系列基于ARM Cortex-M內核的32位微控制器&#xff0c;廣泛應用于嵌入式系統中。 STM32系列由STMicroelectronics&#xff08;意法半導體&#xff09;開發和生產&#xff0c;并憑借其靈活的設計、豐富的外設和強大的生態系統&#xff0c;成為嵌入式…

咬文嚼字:詞元是當今生成式人工智能失敗的一個重要原因

生成式人工智能模型處理文本的方式與人類不同。了解它們基于"標記"的內部環境可能有助于解釋它們的一些奇怪行為和頑固的局限性。從 Gemma 這樣的小型設備上模型到 OpenAI 業界領先的 GPT-4o 模型&#xff0c;大多數模型都建立在一種稱為轉換器的架構上。由于轉換器在…

Ubuntu24.04清理常見跟蹤軟件tracker

盡量一天一更&#xff0c;不刷視頻&#xff0c;好好生活 打開系統監視器&#xff0c;發現開機有個tracker-miner-fs-fs3的跟蹤程序&#xff0c;而且上傳了10kb的數據。 搜索知&#xff0c;該程序會搜集應用和文件的信息。 刪除tracker 顯示帶tracker的apt程序 sudo apt lis…

ThreadLocal的內存泄漏

什么是內存泄漏 程序在申請內存后&#xff0c;無法釋放已申請的內存空間在定義變量時&#xff0c;需要一段內存空間來存儲數據信息&#xff0c;而這段內存如果一直不被釋放&#xff0c;那么就會導致內存被占用光&#xff0c;而被占用的這個對象&#xff0c;一直不能被回收掉&am…