Java精通并发-同步方法访问标志与synchronized关键字之间的关系
继续基于上一次https://www.cnblogs.com/webor2006/p/11428811.html来研究synchronized关键字在字节码中的表现,在上一次文末提出了一个这样的问题:
其对应的源代码如下:
这是因为上面这个同步块中的代码会有抛异常的情况发生,虽说我们肉眼看着好像只有一条打印语句,但是JVM需要考虑同步块抛异常的情况其锁也要正常被释放,所以我们可以看到有异常抛出相关的助记符:
所以可以总结一下:“当我们使用synchronized关键字来修饰代码块时,字节码层面上是通过monitorenter和monitorexit指令来实现的锁的获取和释放动作。”
好,接着来改一下程序:
然后再字节码反编译:
这又如何解释呢?因为该方法无论如何肯定都是以异常进行同步块退出的,这是唯一的可能,没有其它更多的路径,所以这就是为啥只有一个monitorexit助字符存在的原因。
所以又可以总结为:“当线程进入到monitorenter指令后,线程将会持有Monitor对象,退出monitorexit指令后,线程将会释放Monitor对象。”
下面再来改造代码,来让synchronized修饰方法,而非同步块,如下:
那。。对于修饰方法的同步块在字节码中是如何来体现该方法是一个同步方法呢?实际上是通过方向的flag来体现的,如下:
所以,又总结如下:“对于synchronized关键字修饰方法来说,并没有出现monitorenter和monitorexit指令,而是出现了一个ACC_SYNCHRONIZED标志。原因是JVM使用了ACC_SYNCHRONIZED访问标志来区分一个方法是否为同步方法;当方法被调用时,调用指令会检查该方法是否拥有ACC_SYNCHRONIZEDS标志,如果有,那么执行线程将会先持有方法所在对象的Monitor对象,然后再去执行方法体;在该方法执行期间,其他任何线程均无法再获取到这个Monitor对象,当线程执行完该方法后,它会释放掉这个Monitor对象。”
继续再改造:
好,再来看一下此时字节码的情况:
然后此时同步的情况也是体现在flags中的,如下:
最新文章
- PHP精选数组函数
- nginx开启日志,指定格式,查看执行时间
- JAVASE02-Unit08: 文本数据IO操作 、 异常处理
- linux查看某个进程内存占用情况以及/proc/pid/status解释
- WebForm Repeater Response以及 地址栏
- ElasticSearch入门系列(四)分布式初探
- Linux操作、hadoop和sh脚本小结
- HDU 5875 Function (2016年大连网络赛 H 线段树+gcd)
- postgresql数据类型转换
- 动手学servlet(四) cookie和session
- html5 canvas图片反色
- hdoj 2045 不容易系列之(3)—— LELE的RPG难题
- MySQL命令行下查看运行状态
- dll signing issue
- 求一无序数组中第n大的数字 - 快速选择算法
- SCAU Individual Contest #1
- VueJs笔记
- JavaScript中的this详解
- Qt5中表格处理大数据量
- android 分辨率
热门文章
- [LeetCode] 639. Decode Ways II 解码方法 II
- react前端模版Material-UI.类似于antd/bootstrap
- 如何杀死处于进程状态D的进程
- consul多数据中心搭建 【h】
- Postgresql集群解决方案测试报告
- Influx Sql系列教程二:retention policy 保存策略
- [New!!!]欢迎大佬光临本蒟蒻的博客(2019.11.27更新)
- [转帖]helm模板文件chart编写语法详解
- Hive学习(2)
- 05- if-else语句、循环for