Java中锁大致上分为两类:一类是显示锁,一类是隐式锁;今天我们重点来分析一下java中隐式锁的实现:
java中通过synchronized关键字类实现隐式锁:
首先synchronized这个关键字,我们的字节码文件在被翻译为机器语言的时候,这个关键字会直接在synchronized编译为队指令 monitorEnter ,monitorExit ,在这对指令之间的代码,cpu在处理时候,会要求所有访问这一段区域的线程,串行化执行。
![](https://img.haomeiwen.com/i18205378/133e5a114f14424a.png)
![](https://img.haomeiwen.com/i18205378/e994fa43ad1bcc06.png)
![](https://img.haomeiwen.com/i18205378/91cb379bdc6f4e0b.png)
synchronized的语义大致上就是上面的那张图片中所显示的:
在synchronized包裹的代码段中同一时间只能够有一个线程能够访问,其他的线程会在这个时候处于等待状态,知道直到上一个抢道资源的线程执行完毕,同时,在非同步块中的代码,访问时不受限制的。
需要注意的是synchronized 同步块的使用有多种方式:
1.实例方法级别的同步:这个时候被用来作为锁对象的是this对象,如果这个时候this是一个多例的话,jvm实际上在执行的时候不会这段代码加锁,这就是java内置锁的消除
![](https://img.haomeiwen.com/i18205378/df26dfd3565ac679.png)
![](https://img.haomeiwen.com/i18205378/62a772e1f683ca14.png)
3.类对象级别的锁:类对象有两种写法
![](https://img.haomeiwen.com/i18205378/dd3da158098afabc.png)
![](https://img.haomeiwen.com/i18205378/a5685267930b1a82.png)
锁对象的内存结构:
![](https://img.haomeiwen.com/i18205378/9c858413037483a7.png)
![](https://img.haomeiwen.com/i18205378/c46bf0fc288c5985.png)
对象头:这里涉及到一个java内置锁对象的膨胀升级。
![](https://img.haomeiwen.com/i18205378/a01be8a241b4c7c4.png)
![](https://img.haomeiwen.com/i18205378/65af20ac117a5074.png)
synchroized在使用的过程中不能够跨方法使用,我们有没有可能不是java的关键字来自己添加锁呢?
我们可以通过UnSafe 这个类来手动的添加锁和释放锁:
![](https://img.haomeiwen.com/i18205378/0b937c573ef344a7.png)
![](https://img.haomeiwen.com/i18205378/0b11e9688385b71b.png)
锁的粗化:
![](https://img.haomeiwen.com/i18205378/6c7bbc686d81eb48.png)
锁的消除:
![](https://img.haomeiwen.com/i18205378/24fd434f3532287f.png)
java 内置锁的膨胀升级
网友评论