synchronized 關鍵字鎖定範圍侷限於方法/代碼塊,無法跨方法、跨對象協調。Doug Lea 的 concurrent 包引入 Sync 介面,統一鎖、閘、條件變量語義,實現面向抽象編程,靈活切換同步策略。
public interface Sync {
void acquire() throws InterruptedException; // 獲取許可(阻塞)
boolean attempt(long msecs) throws InterruptedException; // 嘗試獲取(帶超時)
void release(); // 釋放許可
}
acquire() / attempt() 可拋 InterruptedException,需捕獲release() 不拋異常,適合 finally 區塊保證釋放class X {
private final Sync gate = new Mutex(); // 或 Semaphore 等
public void m() {
try {
gate.acquire();
try {
// 臨界區業務邏輯
} finally {
gate.release(); // 保證釋放
}
} catch (InterruptedException ex) {
// 中斷應對:記錄、恢復中斷狀態、拋出等
}
}
}
public class Mutex implements Sync {
protected boolean inuse_ = false; // 鎖狀態
public void acquire() throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException(); // (1) 快速失敗
synchronized (this) {
try {
while (inuse_) wait(); // (2) 自旋等待
inuse_ = true; // 佔用鎖
} catch (InterruptedException ex) {
notify(); // (3) 喚醒其他等待者
throw ex;
}
}
}
public synchronized void release() {
inuse_ = false;
notify(); // 喚醒一個等待者
}
public boolean attempt(long msecs) throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException();
synchronized (this) {
if (!inuse_) {
inuse_ = true;
return true;
}
if (msecs <= 0) return false;
long waitTime = msecs;
long start = System.currentTimeMillis();
try {
for (;;) {
wait(waitTime);
if (!inuse_) {
inuse_ = true;
return true;
}
waitTime = msecs - (System.currentTimeMillis() - start);
if (waitTime <= 0) return false;
}
} catch (InterruptedException ex) {
notify();
throw ex;
}
}
}
}
acquire() 會死鎖,簡化實現,效能更高synchronized 前後各檢查一次 Thread.interrupted(),響應更及時synchronized(this) 監視器上,經典條件變量模式release() 無條件喚醒:不檢查是否持有鎖,簡化邏輯,允許「過度釋放」attempt() 精確超時控制:動態計算剩餘等待時間,避免過度/不足等待| 實現類 | 語義 | 典型場景 |
|---|---|---|
Mutex | 互斥鎖(非重入) | 跨方法 before/after 同步 |
Semaphore | 計數信號量 | 資源池控制、限流 |
ReentrantLock | 可重入鎖 | 替代 synchronized、公平鎖 |
Latch / CountDown | 閘/倒數閘 | 多線程啟動同步、階段等待 |