首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ReentrantLock的简单实现

ReentrantLock的简单实现
EN

Code Review用户
提问于 2015-07-21 10:27:00
回答 2查看 5.5K关注 0票数 0

ReentrantLock的实现:

代码语言:javascript
复制
public class ReentrantLock {
    private boolean isLocked = false;
    private Thread lockedBy = null;
    private int lockCount = 0;

    public synchronized void lock() throws InterruptedException{
        while(isLocked && Thread.currentThread() != lockedBy){
            this.wait();
        }
        isLocked = true;
        lockedBy = Thread.currentThread();
        lockCount++;
    }

    public synchronized void unlock(){
        if(Thread.currentThread() == lockedBy){
            lockCount--;
        }
        if(lockCount == 0){
            isLocked = false;
            this.notify();
        }
    }
}
EN

回答 2

Code Review用户

回答已采纳

发布于 2015-07-21 11:45:20

您的代码看起来很合理,除了两个例外,解锁应该只在锁被解锁时通知.您的代码当前允许不对称通知(过多通知)。

考虑:

公共同步无效解锁(){ if(Thread.currentThread() == lockedBy){ lockCount-;} if(lockCount == 0){ isLocked = false;this.notify();}

即使没有任何东西锁定,上面的代码也会发出通知。这一效果可能很小,但重要的是这类类要表现出对称性。守则应是:

代码语言:javascript
复制
public synchronized void unlock(){
    if (!isLocked || lockedBy != Thread.currentThread()) {
        return;
    }
    lockCount--;
    if(lockCount == 0){
        isLocked = false;
        this.notify();
    }
}

另一个漏洞是您泄露了锁的监视器。使用同步方法是一个问题,因为有人可以简单地对整个类进行同步,并将整个系统死锁.考虑一条恶意的线程:

代码语言:javascript
复制
synchronized (lockInstance) {
    Thread.sleep(10000000);
}

现在没有其他线程能够锁定或解锁该实例,并且只会挂起。

您应该使用私有监视器:

代码语言:javascript
复制
private final Object sync = new Object();

然后同步处理:

代码语言:javascript
复制
synchronized (sync) {
   .....
}
票数 12
EN

Code Review用户

发布于 2015-11-02 18:48:35

您还可以去掉isLocked实例变量,并将表达式isLocked替换为lockedBy != null

结合@rofl的建议,我得出以下结论:

代码语言:javascript
复制
class ReentrantLock {
    private final Object sync = new Object(); // private monitor
    private Thread lockedBy = null;  // null => unlocked                        
    private int lockCount = 0;

    public void lock() throws InterruptedException {
        synchronized (sync) {
            Thread callingThread = Thread.currentThread();
            while (lockedBy != null && lockedBy != callingThread)
                wait();
            lockedBy = callingThread; // (re)locked!                            
            lockCount++;
        }
    }

    public void unlock() {
        synchronized (sync) {
            if (Thread.currentThread() == lockedBy)
                if (--lockCount == 0) {
                    lockedBy = null;      // unlocked!                          
                    notify();
                }
        }
    }
}
票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/97568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档