You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中不使用wait()和sleep()实现线程等待(自定义重入锁场景)

可重入锁acquire方法实现方案

首先需要明确,你要实现的是可重入锁,所以必须处理同一个线程重复获取锁的场景,同时在锁被其他线程占用时,通过自旋(忙等)持续尝试获取锁(符合不能用wait()/sleep()的要求)。先修正原代码中的逻辑错误,再给出完整实现:

public class MyReentrantLock implements Lock {
    private AtomicBoolean locked = new AtomicBoolean(false);
    private long idOfThreadCurrentlyHoldingLock;
    private int reentrantCount = 0; // 记录锁的重入次数

    @Override
    public void acquire() {
        long currentThreadId = Thread.currentThread().getId();
        
        // 1. 可重入判断:当前线程已持有锁,直接增加重入次数
        if (idOfThreadCurrentlyHoldingLock == currentThreadId) {
            reentrantCount++;
            return;
        }
        
        // 2. 其他线程自旋尝试CAS获取锁(原标记位置的核心逻辑)
        while (!locked.compareAndSet(false, true)) {
            // 空循环持续尝试CAS,属于忙等,满足禁用wait/sleep的要求
        }
        
        // 3. 获取锁成功后,记录持有线程ID并初始化重入次数
        idOfThreadCurrentlyHoldingLock = currentThreadId;
        reentrantCount = 1;
    }

    @Override
    public boolean tryAcquire() {
        long currentThreadId = Thread.currentThread().getId();
        
        // 可重入判断
        if (idOfThreadCurrentlyHoldingLock == currentThreadId) {
            reentrantCount++;
            return true;
        }
        
        // 尝试一次CAS获取锁
        boolean acquired = locked.compareAndSet(false, true);
        if (acquired) {
            idOfThreadCurrentlyHoldingLock = currentThreadId;
            reentrantCount = 1;
        }
        return acquired;
    }

    @Override
    public void release() {
        long currentThreadId = Thread.currentThread().getId();
        
        // 先校验当前线程是否持有锁,非法释放直接抛异常
        if (idOfThreadCurrentlyHoldingLock != currentThreadId) {
            throw new IllegalReleaseAttempt();
        }
        
        // 重入次数递减,只有次数归0时才真正释放锁
        reentrantCount--;
        if (reentrantCount == 0) {
            locked.set(false);
            idOfThreadCurrentlyHoldingLock = -1; // 重置持有线程ID
        }
    }

    // Lock接口其他方法(如lockInterruptibly、newCondition等)需按需补充实现
}

核心逻辑说明:

  • 可重入处理:通过idOfThreadCurrentlyHoldingLock判断当前线程是否已持有锁,避免同一线程重复获取锁时自我阻塞
  • 自旋等待:当锁被其他线程占用时,进入while循环持续调用compareAndSet尝试抢占锁,完全符合你只能使用AtomicBoolean和Thread类的要求
  • 修正release逻辑:先校验线程合法性,再根据重入次数决定是否真正释放锁,避免错误释放其他线程持有的锁

内容的提问来源于stack exchange,提问作者rachel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 11:15:29