008 Lock锁 | 自定义可重入锁

自定义锁,可以通过实现Lock接口,重写相应的方法即可。代码如下,

private boolean isLocked = false;
private Thread lockBy = null;
private int lockCount = 0;

@Override
public synchronized void lock() {
    Thread currentThread = Thread.currentThread();  
    while (isLocked && currentThread != lockBy) {
        //第一个线程抢到,进来后,isLocked=false,不需要wait,不需要while循环
        //第二个线程来了,如果已经锁了,并且还是锁的那个线程,也不wait,反之,需要wait
        //因此,条件是没有锁的时候,以及锁了以后还是同一个线程,不需wait
        //这里使用while,是为了防止wait被虚拟唤醒,即线程由于某些特殊情况,不是被notify或者notifyAll所唤醒,所以还需要再次判断条件是否成立
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    isLocked = true;
    lockBy = currentThread;
    lockCount++;  
}

@Override
public synchronized void unlock() {
    //这里判断是否是锁的线程,是为了防止Lock对象的unlock方法乱用,在非没有竞争锁的线程中使用了unlock方法
    if (lockBy == Thread.currentThread()) {
        lockCount--;  
        if (lockCount == 0) {
            notify();
            isLocked = false;
        }
    }
}

注意,几个属性,isLocked,lockBy,lockCount,实现可重入的效果的锁。lockCount统计了获得锁的线程,重入了多少次,因此,在unlock的时候,要看释放锁多少次,即,重入多少次,就释放多少次,否则依旧获得锁,无法notify其他阻塞的线程。

你可能感兴趣的:(008 Lock锁 | 自定义可重入锁)