1.synchronized锁的是什么?
JDK源码(notify方法)说明举例
作用于实例方法:当前实例加锁,进入同步代码前要获得当前实例的锁
作用于代码块:对括号里配置的对象加锁
作用于静态方法:对前类加锁,进去同步代码前要获得当前类对象的锁
注:获取不同的锁之间互不影响
2.从字节码角度分析synchronized实现
-
先编译代码
javac Lock_SyncDemo.java -
反编译代码进行分析
javap -c ***.class文件反编译 -
假如你需要更多的信息
javap -v ***.class文件反编译 -v -verbose 输出附加信息(包括行号、本地变量表,反汇编等详细信息)
从三个方面分析synchronized关键字
①同步代码块
实现使用的是monitorenter和monitorexit指令 但是发现只有一个enter,却有两个exit 为什么?
1.正常完成后释放锁
2.保证异常也能正常释放锁
一定是一个enter两个exit吗?
- m1方法里面自己添加一个异常试试
哦吼,添加异常后一个enter对应一个exit!!!
②普通同步方法
javap -v ***.class文件反编译
实现使用的是ACC_SYNCHRONIZED访问标志
调用指令将会检查方法的ACC_SYNCHRONIZED访问标志是否被设置。
如果设置了,执行线程会将先持有monitor然后再执行方法,
最后在方法完成(无论是正常完成还是非正常完成)时释放 monitor
③静态同步方法
javap -v ***.class文件反编译
ACC_STATIC, ACC_SYNCHRONIZED访问标志区分该方法是否静态同步方法
3.反编译synchronized锁的是什么
引入一个概念:管程 monitor
管程 (英语:Monitors,也称为监视器) 是一种程序结构,结构内的多个子程序(对象或模块)形成的多个工作线程互斥访问共享资源。
这些共享资源一般是硬件设备或一群变量。对共享变量能够进行的所有操作集中在一个模块中。(把信号量及其操作原语“封装”在一个对象内部)管程实现了在一个时间点,最多只有一个线程在执行管程的某个子程序。管程提供了一种机制,管程可以看做一个软件模块,它是将共享的变量和对于这些共享变量的操作封装起来,形成一个具有一定接口的功能模块,进程可以调用管程来实现进程级别的并发控制。
在HotSpot虚拟机中,管程monitor采用ObjectMonitor实现
在C++源码中 ObjectMonitor.java→ObjectMonitor.cpp→objectMonitor.hpp
objectMonitor.hpp
每个对象都天生带着一个对象监视器,也就是说任何一个对象都可以作为锁