死磕synchronized一: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对象、进行上锁…
在这里插入图片描述

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

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

这些entry point是什么时候生成的呢?JVM启动的时候,看代码
在这里插入图片描述

那Java中的每个方法,何时与这些入口点进行绑定的呢?在链接阶段。看代码
在这里插入图片描述

好像没看到synchronized修饰的方法的入口点是如何绑定的对吧。这个得追entry_for_method代码逻辑
在这里插入图片描述

如何执行

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

编译系统

JVM在运行时是如何知道我现在要执行的方法有没有被synchronized修饰呢?是通过方法的访问权限为来识别的。
在这里插入图片描述

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

运行系统

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

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

lock_method方法的逻辑是汇编风格写出来的,不太好理解,我就用伪代码解释下
在这里插入图片描述

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

推荐阅读

1、JMM到底如何理解?JMM与MESI到底有没有关系?
2、JVM的多态是如何实现的
3、【手写JVM专栏】二、搭建JVM框架,输出hello world

结语

其实技术这个行业真的不难,如果有人带,打底子1-2年,沉淀2-3年,足矣。我自己一步步探索,走得还算顺利,大概花了七年时间。

给大家看看我之前写的一些项目,证明下我不是在吹牛。我不喜欢吹牛,我也不喜欢水课水文章,内心接受不了。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值