相較於 synchronized,Lock 提供更豐富的控制能力:
lockInterruptibly() 響應中斷,避免死鎖無限等待。tryLock() 立即返回,tryLock(timeout, unit) 支持超時。newCondition() 可創建多個 Condition,實現精細化通知(如生產者/消費者不同隊列)。Lock lock = new ReentrantLock(); // 或 new ReentrantLock(true) 公平鎖
lock.lock();
try {
// 临界區操作
} finally {
lock.unlock(); // 必須在 finally 中釋放
}
public class LockDemo {
public static void main(String[] args) {
Outputer outputer = new Outputer();
new Thread(() -> {
while (true) {
try { Thread.sleep(10); } catch (InterruptedException ignored) {}
outputer.output("zhangsan");
}
}, "Thread-A").start();
new Thread(() -> {
while (true) {
try { Thread.sleep(10); } catch (InterruptedException ignored) {}
outputer.output("lisi");
}
}, "Thread-B").start();
}
}
class Outputer {
private final Lock lock = new ReentrantLock();
public void output(String name) {
lock.lock();
try {
for (char c : name.toCharArray()) {
System.out.print(c);
}
System.out.println();
} finally {
lock.unlock();
}
}
}
public void interruptibleLock(Lock lock) {
try {
lock.lockInterruptibly(); // 可被 interrupt() 中斷
try {
// do work
} finally {
lock.unlock();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 保留中斷狀態
// 處理中斷邏輯
}
}
public boolean tryLockWithTimeout(Lock lock, long timeout, TimeUnit unit) {
try {
return lock.tryLock(timeout, unit); // 超時返回 false,不阻塞無限期
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
class BoundedBuffer {
private final Lock lock = new ReentrantLock();
private final Condition notFull = lock.newCondition();
private final Condition notEmpty = lock.newCondition();
private final Queue queue = new LinkedList<>();
private final int capacity;
public void put(T item) throws InterruptedException {
lock.lock();
try {
while (queue.size() == capacity) notFull.await();
queue.add(item);
notEmpty.signal();
} finally { lock.unlock(); }
}
public T take() throws InterruptedException {
lock.lock();
try {
while (queue.isEmpty()) notEmpty.await();
T item = queue.poll();
notFull.signal();
return item;
} finally { lock.unlock(); }
}
}
基於 AQS(AbstractQueuedSynchronizer),使用 state 表示鎖重入次數,exclusiveOwnerThread 記錄持有線程。非公平鎖嘗試 CAS 直接搶佔,公平鎖檢查 AQS 隊列是否有前驅節點。Condition 依賴 AQS 內部等待隊列實現。
try-with-resources 模式(Java 17+ Lock 實現 AutoCloseable)或 finally 確保釋放。ReadWriteLock 或 StampedLock。