死磕synchronized一:synchronized修饰的方法的执行

简介: 近期准备写一个专栏:从Hotspot源码角度剖析synchronized。前前后后大概有10篇,会全网发,写完后整理成电子书放公众号供大家下载。对本专栏感兴趣的、希望彻彻底底学明白synchronized的小伙伴可以关注一波。电子书整理好了会通过公众号群发告知大家。我的公众号:硬核子牙。

哈喽,大家好,我是江湖人送外号[道格牙]的子牙老师。

近期准备写一个专栏:从Hotspot源码角度剖析synchronized。前前后后大概有10篇,会全网发,写完后整理成电子书放公众号供大家下载。对本专栏感兴趣的、希望彻彻底底学明白synchronized的小伙伴可以关注一波。电子书整理好了会通过公众号群发告知大家。我的公众号:硬核子牙。

市面上关于synchronized的资料已经很多了,我这个专栏跟那些资料有啥差别呢:

  1. 更系统。市面上目前虽然资料众多,但都是零散的。有些资料讲得东西甚至是相互冲突的,都不知道信谁的。我准备从Java层面到JVM层面到操作系统层面系统的去分析用synchronized后呈现的每个现象背后的本质。synchronized很多知识点市面上是没有资料讲的,我给它补上。
  2. 更接近真相。市面上的很多资料,有的是基于字节码解释器那块的代码yy出来的,有的是东拼西凑整合出来的,各个说的都像真的一样,把看的人搞蒙圈了。我准备从模板解释器代码入手,单步调试着研究,有些不确定的自己写代码去证明,争取分享给大家的都是本来如此的知识。不确定的地方我会标注出来。
  3. 授人以鱼不如授人以渔。我会以大家学完后能够手写出synchronized的标准来设计这个专栏。因为从我自己研究的角度来说,抛开语言的障碍,synchronized的每种机制如果让你实现你手足无措,那你还是没有真正地理解synchronized。言外之意就是你不一定要去手写,但是你在脑海中回想,比如CAS、锁膨胀、锁对象加锁解锁……你大概知道代码是怎么写的。

本篇文章是第一篇,聚焦分析JVM是如何执行synchronized修饰的方法的:

  1. 编译系统是如何处理synchronized关键字的
  2. JVM是如何选出锁定的对象的
  3. 模板解释器为了提升效率做了什么
  4. 什么情况会由执行例程切入C++代码
  5. 如何单步调试synchronized

方法入口点

JVM执行Java方法都需要先构建运行环境,再去执行字节码指令。

这个运行环境包括:创建栈帧、从调用者堆栈拷贝参数、给this指针赋值…如果是synchronized修饰的方法,还需要:根据是否是静态方法来计算出锁对象,即是当前对象实例还是Class对象、进行上锁…
image.png

因为调用每个方法都需要构建运行环境,都需要做这些事情,所以JVM把这套流程打包,封装成一个一个的执行流程。在JVM术语中,一般字节码指令的处理逻辑称为执行例程,这里为了做区分,起了个新的名字,叫entry point,翻译过来就是入口点。

JVM中有很多entry point,都存储在entry table中。与方法调用相关的比较常见的是这四个。非native方法一般对应的就是前两个入口点,被synchronized修饰对应的是zerolocals_synchronized,否则是zerolocals。
image.png

这些entry point是什么时候生成的呢?JVM启动的时候,看代码
image.png

那Java中的每个方法,何时与这些入口点进行绑定的呢?在链接阶段。看代码
image.png

好像没看到synchronized修饰的方法的入口点是如何绑定的对吧。这个得追entry_for_method代码逻辑
image.png

如何执行

JVM是如何执行synchronized修饰的方法的呢?这个得从编译阶段、链接阶段、运行阶段三个阶段来分析。任何语言的任何语法糖都是由编译系统与运行系统配合完成的。这三个阶段中,编译阶段是编译系统做的事情,链接阶段与运行阶段是运行系统做的事情。接下来展开来说下。

编译系统

JVM在运行时是如何知道我现在要执行的方法有没有被synchronized修饰呢?是通过方法的访问权限为来识别的。
image.png

这个数据是在编译阶段生成的,通过IDEA插件jclasslib可查看。

运行系统

如果是synchronized代码块,那在链接阶段会把这个方法当成普通的方法来处理,绑定的执行流就是zerolocals,最终处理synchronized逻辑是在执行monitorenter指令时。

如果是synchronized修饰方法,在链接阶段绑定执行流zerolocals_synchronized。这两者的区别是什么呢?其实生成的执行流是同一套代码,区别就是有个判断,如果是synchronized修饰的方法,会执行lock_method。看代码。
image.png

lock_method方法的逻辑是汇编风格写出来的,不太好理解,我就用伪代码解释下
image.png

至此,JVM是如何执行synchronized修饰的方法的逻辑就讲完了。当然,synchronized还有很多很多内容,我会逐步分享给大家。感兴趣的小伙伴可以关注一波。我的公众号:硬核子牙

相关文章
|
2月前
|
Java
Synchronized实现原理(方法代码块)
Synchronized实现原理(方法代码块)
20 0
|
5月前
|
Java
9.synchronized 是个啥东西?应该怎么使用?
9.synchronized 是个啥东西?应该怎么使用?
28 0
9.synchronized 是个啥东西?应该怎么使用?
|
10月前
|
缓存 Java 调度
【JavaEE】多线程之锁(synchronized)与volatile关键字
【JavaEE】多线程之锁(synchronized)与volatile关键字
|
安全 Java Spring
Synchronized代码详解?
Synchronized代码详解?
|
安全 Java 编译器
多线程安全问题原理和解决办法Synchronized和ReentrantLock使用与区别
多线程安全问题原理和解决办法Synchronized和ReentrantLock使用与区别
|
前端开发 Java 程序员
彻底读懂ThreadLocal与Synchronized区别(代码案例详解)
📝本篇用案例代码带初学者彻底读懂ThreadLocal与Synchronized区别!
135 0
彻底读懂ThreadLocal与Synchronized区别(代码案例详解)
|
SQL 安全 NoSQL
在Spring事务管理下,Synchronized为啥还线程不安全?
文本已收录至我的GitHub仓库,欢迎Star:github.com/bin39232820… 种一棵树最好的时间是十年前,其次是现在
118 0
|
缓存 Java 编译器
因为我说:volatile 是轻量级的 synchronized,面试官让我回去等通知!
因为我说:volatile 是轻量级的 synchronized,面试官让我回去等通知!
97 0
因为我说:volatile 是轻量级的 synchronized,面试官让我回去等通知!
|
存储 前端开发 Java
Synchronized 天天用,实现原理你懂吗?
Synchronized 天天用,实现原理你懂吗?
123 0
Synchronized 天天用,实现原理你懂吗?