Welcome everyone

可重入锁

java 汪明鑫 790浏览 0评论

设计一个不可重入锁

public class Lock{
    private boolean isLocked = false;
    public synchronized void lock() throws InterruptedException{
        while(isLocked){    
            wait();
        }
        isLocked = true;
    }
    public synchronized void unlock(){
        isLocked = false;
        notify();
    }
}

使用这个不可重入锁

public class Count {
    selfLock lock = new selfLock();
    public void print() throws InterruptedException {
        lock.lock();
        System.out.println("调用doAdd()...");
        doAdd();
        lock.unlock();
    }
    public void doAdd() throws InterruptedException {
        lock.lock();
        System.out.println("进入doAdd() # dosomething...");
        lock.unlock();
    }

    public static void main(String []args) throws InterruptedException {
        Count c=new Count();
        c.print();
    }
}

 

不可重入锁也叫自旋锁

设计一个可重入锁

public class Lock{
    boolean isLocked = false;
    Thread  lockedBy = null;
    int lockedCount = 0;
    public synchronized void lock()
            throws InterruptedException{
        Thread thread = Thread.currentThread();
        while(isLocked && lockedBy != thread){
            wait();
        }
        isLocked = true;
        lockedCount++;
        lockedBy = thread;
    }
    public synchronized void unlock(){
        if(Thread.currentThread() == this.lockedBy){
            lockedCount--;
            if(lockedCount == 0){
                isLocked = false;
                notify();
            }
        }
    }
}

同样的方法使用可重入锁

public class Count1 {
    newLock lock = new newLock();
    public void print() throws InterruptedException {
        lock.lock();
        System.out.println("调用doAdd()...");
        doAdd();
        lock.unlock();
    }
    public void doAdd() throws InterruptedException {
        lock.lock();
        System.out.println("进入doAdd() # dosomething...");
        lock.unlock();
    }

    public static void main(String []args) throws InterruptedException {
        Count1 c=new Count1();
        c.print();
    }
}

 

可重入就意味着:线程可以进入任何一个它已经拥有的锁所同步着的代码块

 

可重入锁
每次成功的申请锁以后,要记录到底是谁申请的,还要用一个计数器记录重入的次数,持有锁的家伙再次申请锁只是给计数器加1
释放锁时,把计数器减1,等于0才表示真正的释放锁

 

重入进一步提升了加锁行为的封装性
重入避免了死锁情况的方生

 

 

转载请注明:汪明鑫的个人博客 » 可重入锁

喜欢 (0)

说点什么

您将是第一位评论人!

提醒
avatar
wpDiscuz