简单分析synchronized不会锁泄漏的原因
最近看到一句话:内部锁synchronized不会造成锁泄漏(Lock Leak)。
锁泄漏是指一个线程获得某个锁以后,由于程序的错误、缺陷致使该锁一直没法被释放而导致其他线程一直无法获得该锁的现象。(摘自《Java多线程编程实战指南(核心篇)》--黄文海)
很好奇JVM是怎么保证的。
我想,Java代码,最终无非是编译成字节码,变成一条条指令,或许可以从指令入手研究一下。
1. 一个小例子
我们先来看看下面的代码。
public class SynchronizedTest {
private static final Object LOCK = new Object();
public static void main(String[] args) {
synchronized (LOCK) {
foo();
}
}
public static void foo() {
//do something...
}
}
很简单的一段代码,在临界区调用了一个方法。
通过javap -c SynchronizedTest.class ,得到如下信息,重点关注红框部分:

第5和第10行分别是monitorenter 和 monitorexit,这表示进入和退出临界区,临界区中间第6行调用了foo()这个方法。当退出临界区后,第11行直接goto第19行,即return,从当前方法返回,方法结束。
这是正常情况下的执行顺序。
那么如果在临界区中发生了异常(本例中是foo()可能发生异常),执行顺序又是怎么样的呢?
2. 异常表
在研究执行顺序之前,先学习一下异常表。
异常表实际上是Java代码的一部分,编译器使用异常表而不是简单的跳转命令来实现Java异常及finally处理机制。
上图的 Exception table即为异常表。它列举了哪些代码行的范围内,可能出现某种异常时,对应的处理机制。
【
那么异常表用在什么时候呢?
答案是异常发生的时候,当一个异常发生时
1.JVM会在当前出现异常的方法中,查找异常表,是否有合适的处理者来处理
2.如果当前方法异常表不为空,并且异常符合处理者的from和to节点,并且type也匹配,则JVM调用位于target的调用者来处理。
3.如果上一条未找到合理的处理者,则继续查找异常表中的剩余条目
4.如果当前方法的异常表无法处理,则向上查找(弹栈处理)刚刚调用该方法的调用处,并重复上面的操作。
5.如果所有的栈帧被弹出,仍然没有处理,则抛给当前的Thread,Thread则会终止。
6.如果当前Thread为最后一个非守护线程,且未处理异常,则会导致JVM终止运行。
以上就是JVM处理异常的一些机制。
】--以上摘自 详解JVM如何处理异常
具体到本例中
1. 当临界区发生异常,JVM查找异常表,发现符合第一行记录(异常发生点在6和11行(不包括第11行)之间,任意异常类型),于是跳到第14行,即第10行的monitorexit要么不执行,要么执行抛出异常,总之无法成功执行。
2. 从14行一路执行下去,到16行,再次monitorexit,此时释放锁。18行抛出上面获取到的异常,19行从当前方法返回void, 结束方法的运行。
3. 如果第2步过程中又发生异常,根据异常表第二行记录(异常点发生在14和17行(不包括第17行)之间,任意异常类型),会再次跳到14行,重新执行第2步,循环直到monitorexit指令成功执行。
这样就保证了monitorexit一定能够执行成功,锁一定会被释放。
简单分析synchronized不会锁泄漏的原因的更多相关文章
- java里的锁总结(synchronized隐式锁、Lock显式锁、volatile、CAS)
一.介绍 首先, java 的锁分为两类: 第一类是 synchronized 同步关键字,这个关键字属于隐式的锁,是 jvm 层面实现,使用的时候看不见: 第二类是在 jdk5 后增加的 Lock ...
- (转)Synchronized(对象锁)和Static Synchronized(类锁)的区别
场景:面试的时候经常用得到! 1 综述 Synchronized和Static Synchronized区别 一个是实例锁(锁在某一个实例对象上,如果该类是单例,那么该锁也具有全局锁的概念),一个是全 ...
- 线程安全(中)--彻底搞懂synchronized(从偏向锁到重量级锁)
接触过线程安全的同学想必都使用过synchronized这个关键字,在java同步代码快中,synchronized的使用方式无非有两个: 通过对一个对象进行加锁来实现同步,如下面代码. synchr ...
- Java多线程系列 基础篇06 synchronized(同步锁)
转载 http://www.cnblogs.com/paddix/ 作者:liuxiaopeng http://www.infoq.com/cn/articles/java-se-16-synchro ...
- 关于Synchronized的偏向锁,轻量级锁,重量级锁,锁升级过程,自旋优化,你该了解这些
前言 相信大部分开发人员,或多或少都看过或写过并发编程的代码.并发关键字除了Synchronized(如有不懂请移至传送门,关于Synchronized的偏向锁,轻量级锁,重量级锁,锁升级过程,自旋优 ...
- 精通java并发-synchronized关键字和锁
目前CSDN,博客园,简书同步发表中,更多精彩欢迎访问我的gitee pages synchronized关键字和锁 示例代码 public class MyThreadTest2 { public ...
- 再有人说synchronized是重量级锁,就把这篇文章扔给他看
synchronized作为Java程序员最常用同步工具,很多人却对它的用法和实现原理一知半解,以至于还有不少人认为synchronized是重量级锁,性能较差,尽量少用. 但不可否认的是synchr ...
- JAVA多线程之Synchronized关键字--对象锁的特点
一,介绍 本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点. 所谓对象锁,就是就是synchronized 给某个对象 加锁.关于 对象锁 可参考:这篇文章 二,分析 s ...
- AbstractQueuedSynchronizer的简单分析
说明:本作者是文章的原创作者,转载请注明出处:本文地址:http://www.cnblogs.com/qm-article/p/7955781.html 一.AbstractQueuedSynchro ...
随机推荐
- 微信小程序开发常见坑
前段时间稍微涉猎了微信小程序开发,踩了一些坑,在此总结出来,希望能为小伙伴们提供一点帮助. 页面跳转 对于页面跳转,可能习惯性想到wx.navigateTo,但是在跳转到目标页面是一个tab时,此接口 ...
- 问题MySQL Error (2013): Lost connection to MySQL server at waiting for initial communication packet
错误说明: SQL Error (2013): Lost connection to MySQL server at 'waiting for initial communication packet ...
- SQL-W3School-高级:SQL FULL JOIN 关键字
ylbtech-SQL-W3School-高级:SQL FULL JOIN 关键字 1.返回顶部 1. SQL FULL JOIN 关键字 只要其中某个表存在匹配,FULL JOIN 关键字就会返回行 ...
- C++ STL 排序
#include <iostream>#include <algorithm>#include <deque>#include <vector>#inc ...
- C++ STL swap_range
#include <iostream>#include <vector>#include <deque>#include <algorithm> usi ...
- 配置Xmanager远程登录
1.修改/etc/gdm/custom.conf文件找到下面的语句:[security]AllowRemoteRoot=true[xdmcp]Enable=true修改custom.conf后,必须重 ...
- Java 代码快速注释 和 取消注释
注释掉代码: 把要注释的代码选中: 加/* */ 形式的注释 -> Ctrl+Shift+/ 加 //形式的形式的注释 -> ctrl+/ 取消代码注释: 把要取消注释的代码选中: ...
- EasyNetQ使用(五)【基于主题的路由,控制队列名称】
RabbitMQ有一个很酷的功能,基于主题的路由,这个功能允许订阅者基于多个条件去过滤消息.一个主题是由点号分隔的单词列表,随消息一同发布.例如:“stock.usd.nyse” 或 “book.uk ...
- WhatsApp Group vs WhatsApp Broadcast for Business
WhatsApp Group vs WhatsApp Broadcast for Business By Iaroslav Kudritskiy If you've read our Ultimate ...
- ESXi 虚拟机 提示 无法打开本地虚拟机的 xxx.vmx 的本地管道的 问题解决.
1. 今天同事与我联系, 说一个虚拟机出现连不上, vcenter控制台关闭虚拟机之后 再次打开报错: 2. 自己最开始的解决方法 移除虚拟机, 进入服务器的datastore 重新注册, 结果发现问 ...