# 并發編程中Semaphore的使用方法
## 引言
在并發編程中,控制對共享資源的訪問是一個核心挑戰。Semaphore(信號量)作為一種經典的同步機制,由荷蘭計算機科學家Dijkstra于1965年提出,能夠有效管理多線程/進程對有限資源的訪問。本文將深入探討Semaphore的工作原理、使用場景及代碼實現。
## 一、Semaphore基本概念
### 1.1 什么是Semaphore
Semaphore是一種計數器,用于控制訪問特定資源的線程數量。它維護一組許可證(permits):
- 線程通過`acquire()`獲取許可證(計數器減1)
- 通過`release()`釋放許可證(計數器加1)
- 當計數器為0時,新線程必須等待
### 1.2 核心特性
- **計數機制**:可設置為任意非負整數值
- **原子性操作**:所有操作都是線程安全的
- **公平性選擇**:支持公平/非公平模式
- **可中斷性**:支持帶超時的獲取操作
## 二、Semaphore類型
### 2.1 二進制信號量
```java
Semaphore binarySem = new Semaphore(1); // 相當于互斥鎖
Semaphore poolSem = new Semaphore(10); // 允許10個線程同時訪問
public class PrinterQueue {
private final Semaphore semaphore;
public PrinterQueue(int slots) {
semaphore = new Semaphore(slots);
}
public void printJob(Object document) {
try {
semaphore.acquire();
// 實際打印操作
System.out.println(Thread.currentThread().getName()
+ " is printing...");
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
semaphore.release();
}
}
}
// 嘗試獲取許可(非阻塞)
if(semaphore.tryAcquire()) {
try {
// 臨界區代碼
} finally {
semaphore.release();
}
}
// 帶超時的獲取
if(semaphore.tryAcquire(1, TimeUnit.SECONDS)) {
// ...
}
// 公平模式(防止線程饑餓)
Semaphore fairSem = new Semaphore(5, true);
class ConnectionPool {
private final Semaphore sem = new Semaphore(MAX_CONNECTIONS);
public Connection getConnection() throws InterruptedException {
sem.acquire();
return createConnection();
}
public void releaseConnection(Connection conn) {
closeConnection(conn);
sem.release();
}
}
Semaphore full = new Semaphore(0); // 初始0個產品
Semaphore empty = new Semaphore(BUFFER_SIZE); // 初始空位
// 生產者
empty.acquire();
buffer.put(item);
full.release();
// 消費者
full.acquire();
buffer.take();
empty.release();
class RateLimiter {
private final Semaphore sem;
private final int maxPermits;
public RateLimiter(int permits) {
this.sem = new Semaphore(permits);
this.maxPermits = permits;
}
public void refill() {
int missing = maxPermits - sem.availablePermits();
if(missing > 0) sem.release(missing);
}
}
acquire()
和release()
成對出現機制 | 特點 | 適用場景 |
---|---|---|
Semaphore | 控制訪問線程數量 | 資源池、限流 |
ReentrantLock | 獨占訪問 | 需要嚴格互斥的場景 |
CountDownLatch | 一次性等待多個事件完成 | 初始化階段 |
CyclicBarrier | 多線程相互等待 | 并行計算分階段處理 |
Semaphore作為并發編程的基礎工具,其靈活性和實用性使其在資源管理、流量控制等場景中發揮著重要作用。合理使用Semaphore可以顯著提高系統的吞吐量和穩定性,但需要開發者深入理解其工作機制以避免潛在問題。建議在實際開發中結合具體需求選擇合適的同步策略。
本文示例基于Java實現,其他語言(如Python的
threading.Semaphore
、C++的<semaphore>
)也有類似實現,原理相通。 “`
注:本文實際約1100字,包含代碼示例和結構化說明??筛鶕枰{整代碼語言或補充特定框架的實現細節。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。