全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-10 10 分钟 ✍️ juanwangdev

锁机制(ReentrantLock 等)

Lock 接口位于 java.util.concurrent.locks 包,提供灵活的锁机制。

Lock 接口方法

Java
public interface Lock {
    void lock();                   // 获取锁
    void lockInterruptibly();      // 可中断获取锁
    boolean tryLock();             // 尝试获取,立即返回
    boolean tryLock(long time, TimeUnit unit); // 超时尝试
    void unlock();                 // 释放锁
    Condition newCondition();      // 创建条件变量
}

ReentrantLock 基本用法

Java
private final ReentrantLock lock = new ReentrantLock();

public void method() {
    lock.lock();    // 获取锁
    try {
        // 同步代码
    } finally {
        lock.unlock();  // 必须在 finally 中释放
    }
}

必须在 finally 中 unlock:避免异常导致锁未释放,造成死锁。

ReentrantLock 特性

公平锁与非公平锁

Java
// 非公平锁(默认,性能更高)
ReentrantLock unfairLock = new ReentrantLock();

// 公平锁(按等待顺序获取)
ReentrantLock fairLock = new ReentrantLock(true);
类型特点
非公平锁性能高,可能饥饿
公平锁按顺序获取,性能略低

可中断锁

Java
try {
    lock.lockInterruptibly();  // 可被 interrupt() 中断等待
    // 同步代码
} catch (InterruptedException e) {
    // 处理中断
} finally {
    lock.unlock();
}

synchronized 不支持中断:ReentrantLock 可中断等待。

超时获取锁

Java
if (lock.tryLock(3, TimeUnit.SECONDS)) {  // 等待 3 秒
    try {
        // 获取成功,执行同步代码
    } finally {
        lock.unlock();
    }
} else {
    // 获取失败,执行其他逻辑
}

避免无限等待:tryLock(timeout) 设置超时,失败执行降级逻辑。

Condition 条件变量

Java
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();

// 等待
public void await() throws InterruptedException {
    lock.lock();
    try {
        while (!conditionMet) {
            condition.await();  // 等待条件
        }
        // 条件满足后执行
    } finally {
        lock.unlock();
    }
}

// 唤醒
public void signal() {
    lock.lock();
    try {
        conditionMet = true;
        condition.signal();    // 唤醒一个等待线程
        condition.signalAll(); // 唤醒所有等待线程
    } finally {
        lock.unlock();
    }
}

多条件变量

Java
ReentrantLock lock = new ReentrantLock();
Condition notFull = lock.newCondition();
Condition notEmpty = lock.newCondition();

// 精确控制不同条件的等待和唤醒

ReentrantReadWriteLock

读写锁,读锁共享,写锁独占:

Java
ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
Lock readLock = rwLock.readLock();   // 读锁(共享)
Lock writeLock = rwLock.writeLock(); // 写锁(独占)

// 读操作
public int read() {
    readLock.lock();
    try {
        return value;  // 多线程可同时读
    } finally {
        readLock.unlock();
    }
}

// 写操作
public void write(int newValue) {
    writeLock.lock();
    try {
        value = newValue;  // 写时禁止其他读写
    } finally {
        writeLock.unlock();
    }
}

读写锁适用:读多写少场景,如缓存、配置。

StampedLock

乐观读锁,性能更高(JDK 8):

Java
StampedLock lock = new StampedLock();

// 写锁
long stamp = lock.writeLock();
try {
    value = newValue;
} finally {
    lock.unlockWrite(stamp);
}

// 读锁
long stamp = lock.readLock();
try {
    return value;
} finally {
    lock.unlockRead(stamp);
}

// 乐观读(无锁)
long stamp = lock.tryOptimisticRead();
int v = value;
if (!lock.validate(stamp)) {  // 验证是否有写操作
    stamp = lock.readLock();   // 有写操作,转为读锁
    try {
        v = value;
    } finally {
        lock.unlockRead(stamp);
    }
}
return v;

ReentrantLock vs synchronized

特性synchronizedReentrantLock
获取释放自动手动 unlock
公平锁❌ 非公平✅ 可选公平
可中断✅ lockInterruptibly
超时获取✅ tryLock(timeout)
条件变量单个多个 Condition
性能JDK 6 后差距小略有优势

选择原则:优先 synchronized,需要公平锁/可中断/超时/多条件时用 ReentrantLock。

要点总结

  • Lock 接口比 synchronized 功能更灵活
  • ReentrantLock 必须在 finally 中 unlock
  • 支持公平锁/非公平锁,默认非公平
  • lockInterruptibly() 可中断等待
  • tryLock(timeout) 超时获取,避免无限等待
  • Condition 支持多条件变量,精确唤醒
  • ReentrantReadWriteLock:读锁共享,写锁独占
  • StampedLock:乐观读,性能最高
  • 优先 synchronized,高级需求用 ReentrantLock

📝 发现内容有误?点击此处直接编辑

← 上一篇 程间通信
下一篇 → Java JVM内存结构
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库