写点什么

Java- 可重入锁

用户头像
hepingfly
关注
发布于: 2021 年 01 月 24 日
Java-可重入锁

可重入锁:

可重入锁又叫递归锁。是指同一个线程在外层方法获取锁的时候,进入该线程的内层方法会自动获取锁(前提是锁对象是同一个对象)。不会因为之前已经获取过锁还没释放而阻塞。


Java 中 ReentrantLocksynchronized 都是可重入锁,可重入锁的一个优点是一定程度上可以避免死锁。


生活中的例子类比:

家里的大门有一把锁,卫生间有一把锁,在进入大门之后就可以自动进入卫生间,而不需要阻塞等待。


可重入锁的种类:


  • 隐式锁(synchronized 关键字使用的锁)默认是可重入锁。

  • 显示锁(即 Lock)也有 ReentrantLock 这样的可重入锁。


synchronized 可重入锁代码证明:

  • 同步代码块

public class SynchronizedDemo {    static Object obj = new Object();    public static void method1() {        new Thread(() -> {            // 一个线程在外层方法获取锁之后,进入到内层方法就会自动获取锁            synchronized (obj) {                System.out.println(Thread.currentThread().getName() + "外层方法调用");                synchronized (obj) {                    System.out.println(Thread.currentThread().getName() + "中层方法调用");                    synchronized (obj) {                        System.out.println(Thread.currentThread().getName() + "内层方法调用");                    }                }            }        },"thread1").start();    }    public static void main(String[] args) {        method1();    }
复制代码


  • 同步方法

public class SynchronizedDemo2 {    public synchronized void method1() {        System.out.println("外层方法");        method2();    }    public synchronized void method2() {        System.out.println("中层方法");        method3();    }    public synchronized void method3() {        System.out.println("内层方法");    }    public static void main(String[] args) {        new SynchronizedDemo2().method1();
}}
复制代码


synchronized 可重入的实现机制:


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

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

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

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


更多有意思的内容可以关注我的视频号



每天更新一个视频,给你分享一个干货


发布于: 2021 年 01 月 24 日阅读数: 23
用户头像

hepingfly

关注

视频号:hepingfly 分享干货,欢迎关注~ 2018.06.23 加入

B站程序员。目标是做一个有才华,身上有光的男人。

评论

发布
暂无评论
Java-可重入锁