LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 242|回复: 0

Java Synchronized 可重入原理:加锁次数计数器

[复制链接]
发表于 2024-1-9 16:41:47 | 显示全部楼层 |阅读模式

什么是可重入?可重入锁?
可重入:(来源于维基百科)若一个程序或子程序可以“在任意时刻被中断然后操作系统调度执行另外一段代码,这段代码又调用了该子程序不会出错”,则称其为可重入(reentrant或re-entrant)的。即当该子程序正在运行时,执行线程可以再次进入并执行它,仍然获得符合设计时预期的结果。与多线程并发执行的线程安全不同,可重入强调对单个线程执行时重新进入同一个子程序仍然是安全的。

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

看如下的例子

public class SynchronizedDemo {

    public static void main(String[] args) {
        SynchronizedDemo demo =  new SynchronizedDemo();
        demo.method1();
    }

    private synchronized void method1() {
        System.out.println(Thread.currentThread().getId() + ": method1()");
        method2();
    }

    private synchronized void method2() {
        System.out.println(Thread.currentThread().getId()+ ": method2()");
        method3();
    }

    private synchronized void method3() {
        System.out.println(Thread.currentThread().getId()+ ": method3()");
    }
}

结合前文中加锁和释放锁的原理,不难理解:

执行monitorenter获取锁
(monitor计数器=0,可获取锁)
执行method1()方法,monitor计数器+1 -> 1 (获取到锁)
执行method2()方法,monitor计数器+1 -> 2
执行method3()方法,monitor计数器+1 -> 3

执行monitorexit命令
method3()方法执行完,monitor计数器-1 -> 2
method2()方法执行完,monitor计数器-1 -> 1
method2()方法执行完,monitor计数器-1 -> 0 (释放了锁)
(monitor计数器=0,锁被释放了)

这就是Synchronized的重入性,即在同一锁程中,每个对象拥有一个monitor计数器,当线程获取该对象锁后,monitor计数器就会加一,释放锁后就会将monitor计数器减一,线程不需要再次获取同一把锁。

------
原文链接:https://pdai.tech/md/java/thread/java-thread-x-key-synchronized.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表