Java锁系列之可重入锁

Java锁系列之可重入锁

大家好,我是栗子为

今天想和大家分享Java锁系列的一个经典问题,什么是可重入锁?

话不多说,我们一起来看看可重入锁的原理



01


什么是可重入锁


可重入锁又名递归锁,是指同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提是锁对象是同一个对象)

Java中synchronizedReentrantLock都是可重入锁,在一定程度上可避免死锁



02


可重入锁的分类


隐式锁

synchronized关键字既可以修饰同步代码块,又可以修饰同步方法

在一个synchronized修饰的方法或代码块内部调用本类的其他synchronized修饰的方法或代码块时,是永远可以得到锁的

举个栗子

public static void main(String[] args) {
    final Object object = new Object();
    new Thread(()->{
        synchronized (object){
            System.out.println(Thread.currentThread().getName()+"外层加锁");
            synchronized (object){
                System.out.println(Thread.currentThread().getName()+"中层加锁");
                synchronized (object){
                    System.out.println(Thread.currentThread().getName()+"内层加锁");
                }
            }
        }
    },"t1").start();
}

结果如下

t1外层加锁
t1中层加锁
t1内层加锁

我们可以看到,synchronized关键字默认就是可重入锁,不会发生死锁问题

显式锁

Lock类中也有ReentrantLock这样的可重入锁



03


可重入锁实现原理(synchronized)


  1. 每个锁对象拥有一个锁计数器和一个指向持有该锁的线程的指针

  2. 当执行monitorenter时,如果目标锁对象的计数器为0,那么说明它没有被其他线程所持有,Java虚拟机会将该锁对象的持有线程设置为当前线程,并且将其计数器加1

  3. 在目标锁对象的计数器不为0的情况下,如果锁对象的持有线程是当前线程,那么Java虚拟机可以将其计数器加1,否则需要等待,直至持有线程释放该锁

  4. 当执行monitorexit时,Java虚拟机则需将锁对象的计数器减1,计数器为0代表锁已被释放

举个栗子

public class Main{
    static Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        new Thread(()->{
            lock.lock();
            try{
                System.out.println(Thread.currentThread().getName()+"外层加锁");
                lock.lock();
                try{
                    System.out.println(Thread.currentThread().getName()+"内层加锁");
                }finally {
                    lock.unlock();
                }
            }finally {
                lock.unlock();
            }
        },"t1").start();
    }
}

结果如下

t1外层加锁
t1内层加锁

若此时在一个线程中,lock与unlock次数不匹配,导致计数器不为0,那么其他线程若想拿到锁,则需一直等待,所以为了避免此问题,在finally代码块中,执行lock.unlock()方法



04


总结



可重入锁可以用一句话来解释:

一个线程中的多个流程可以获取同一把锁,持有这把同步锁可以再次进入,并且自己可以获取自己的内部锁。

好了,今天的内容就分享到这,小为也是出了好几期并发编程的专题了,希望能对大家有帮助

关注六只栗子,面试不迷路

作者    栗子为

编辑   一口栗子  


Java锁系列之可重入锁

Java锁系列之可重入锁

Java锁系列之可重入锁

Java锁系列之可重入锁



原文始发于微信公众号(六只栗子):Java锁系列之可重入锁

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/88283.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!