美文网首页
可重入锁vs不可重入锁

可重入锁vs不可重入锁

作者: 归来依旧少女 | 来源:发表于2019-06-16 21:08 被阅读0次

    一、代码展示

    先设计一个不可重入锁:

    public class UnreentrantLock {
    
    private Thread localThread;
    
    private boolean isLocked = false;
    
    /**
    
    * 加锁
    
    * @throws InterruptedException
    
    */
    
    public synchronized void lock() throws InterruptedException {
    
    while(isLocked) {
    
    System.out.println(Thread.currentThread().getName()+"没有获取到锁,等待中");
    
    wait();
    
    }
    
    isLocked = true;
    
    localThread = Thread.currentThread();
    
    System.out.println(localThread.getName()+"获取到锁");
    
    }
    
    /**
    
    * 解锁
    
    */
    
    public void unlock() {
    
    if(isLocked) {
    
    System.out.println(Thread.currentThread().getName()+"释放锁");
    
    isLocked = false;
    
    localThread = null;
    
    }
    
    }
    
    }
    
    
    
    测试:
    
    public class Count {
    
    private UnreentrantLock lock = new UnreentrantLock();
    
    public void print() {
    
    try {
    
    lock.lock();
    
    System.out.println("print start..");
    
    //调用add()方法
    
    add();
    
    lock.unlock();
    
    } catch (InterruptedException e) {
    
    e.printStackTrace();
    
    }
    
    }
    
    public void add() {
    
    try {
    
    lock.lock();
    
    System.out.println("add...");
    
    lock.unlock();
    
    } catch (InterruptedException e) {
    
    e.printStackTrace();
    
    }
    
    }
    
    public static void main(String[] args) {
    
    Count count = new Count();
    
    count.print();
    
    }
    
    }
    

    运行结果:

    main获取到锁
    
    print start..
    
    main没有获取到锁,等待中
    

    可以看到同一个线程,重复获取锁失败,形成死锁,这就是不可重入锁。

    然后再写一个可重入锁:

    public class ReentrantLock {
    
    private Thread localThread = null;
    
    private boolean isLocked = false;
    
    private int lockedCount = 0;
    
    /**
    
    * 加锁
    
    *
    
    * @throws InterruptedException
    
    */
    
    public synchronized void lock() throws InterruptedException {
    
    Thread thread = Thread.currentThread();
    
    while (isLocked && localThread != thread) {
    
    System.out.println(Thread.currentThread().getName() + "没有获取到锁,等待中");
    
    wait();
    
    }
    
    isLocked = true;
    
    localThread = thread;
    
    lockedCount++;
    
    System.out.println(localThread.getName() + "获取到锁");
    
    }
    
    /**
    
    * 解锁
    
    */
    
    public void unlock() {
    
    if (isLocked) {
    
    System.out.println(Thread.currentThread().getName() + "释放锁");
    
    lockedCount--;
    
    if (lockedCount == 0) {
    
    isLocked = false;
    
    localThread = null;
    
    }
    
    }
    
    }
    
    }
    

    测试:

    private ReentrantLock lock = new ReentrantLock();
    

    运行结果:

        main获取到锁
    
        print start..
    
        main获取到锁
    
        add...
    
        main释放锁
    
        main释放锁
    

    可以看到,同一个线程可以多次获取锁。

    二、总结

    可重入锁又称之为递归锁,就是一个线程在外层方法获取到锁,在内层方法自动获取到锁,而不会因为没有获取到锁而阻塞。java中的ReentrantLock和synchronized都是可重入锁。可重入锁可一定程度上减少死锁,而不可重入锁则再容易发生死锁。

    相关文章

      网友评论

          本文标题:可重入锁vs不可重入锁

          本文链接:https://www.haomeiwen.com/subject/ltngfctx.html