synchronized关键字:无锁 VS 偏向锁 VS 轻量级锁 VS 重量级锁

1.简介

synchronized是一个jvm层次的关键字,可以同步某一段代码。与ReentrantLock不同,它不可被中断。

synchronized的四个演变阶段: 无锁->偏向锁->轻量级锁->重量级锁

下面是一些相关知识:

Monitor
Monitor可以理解为一个同步工具或一种同步机制,通常被描述为一个对象。每一个Java对象就有一把看不见的锁,称为内部锁或者Monitor锁。

Monitor是线程私有的数据结构,每一个线程都有一个可用monitor record列表,同时还有一个全局的可用列表。每一个被锁住的对象都会和一个monitor关联,同时monitor中有一个Owner字段存放拥有该锁的线程的唯一标识,表示该锁被这个线程占用。

synchronized通过Monitor来实现线程同步,Monitor是依赖于底层的操作系统的Mutex Lock(互斥锁)来实现的线程同步。

Java 对象头
对象头主要包括两部分数据:Mark Word(标记字段)、Klass Pointer(类型指针)

Mark Word:默认存储对象的HashCode,分代年龄和锁标志位信息。(Mark Word中存储的内容与锁的标志位的关系如下)

Klass Point:对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
在这里插入图片描述
JDK1.6之前synchronized:在使用非自旋锁(互斥锁)时,“阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成,这种状态转换需要耗费处理器时间。如果同步代码块中的内容过于简单,状态转换消耗的时间有可能比用户代码执行的时间还要长”。这种方式就是synchronized最初实现同步的方式,这就是JDK 6之前synchronized效率低的原因。这种依赖于操作系统Mutex Lock所实现的锁我们称之为“重量级锁”

2. 无锁

无锁的特点就是修改操作在循环内进行,线程会不断的尝试修改共享资源。如果没有冲突就修改成功并退出,否则就会继续循环尝试。也就是CAS(CAS是基于无锁机制实现的)。

3.偏向锁

偏向锁是指一段同步代码一直被一个线程所访问,那么该线程会自动获取锁,降低获取锁的代价。

会在Mark Word里存储锁偏向的线程ID。在线程进入和退出同步块时不再通过CAS操作来加锁和解锁,而是检测Mark Word里是否存储着指向当前线程的偏向锁。引入偏向锁是为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径,因为轻量级锁的获取及释放依赖多次CAS原子指令,而偏向锁只需要在置换ThreadID的时候依赖一次CAS原子指令即可。

偏向锁只有遇到其他线程尝试竞争偏向锁时,持有偏向锁的线程才会释放锁,线程不会主动释放偏向锁。

4.轻量级锁

是指当锁是偏向锁的时候,被另外的线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,从而提高性能。

若当前只有一个等待线程,则该线程通过自旋进行等待。但是当自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁升级为重量级锁。

5.重量级锁

升级为重量级锁时,锁标志的状态值变为“10”,此时Mark Word中存储的是指向重量级锁的指针,此时等待锁的线程都会进入阻塞状态。重量级锁会用到monitor,jdk1.5之前sychronized都是重量级锁,前面两种事jdk1.5以后的优化。

monitor对象重要属性说明:

_owner:指向持有ObjectMonitor对象的线程

_WaitSet:存放处于wait状态的线程队列

_EntryList:存放处于等待锁block状态的线程队列

_recursions:锁的重入次数

_count:用来记录该线程获取锁的次数

假如当前线程A、B、C同时访问同步块。假如A获取到锁,也就会将 monitor 对象中的 _owner 的值赋值为当前线程ID。B、C线程会进入EntryList中。count =1 ,recursions=1。假如A线程第二次进入同步快,count = 2, recursions=2,当前线程退
出时,count和recursions会减一,直到count=0, recursions=0时,说明线程A释放了monitor锁,然后会唤醒EntryList中的线程,EntryList线程会竞争monitor,竞争到了,和线程A的操作一致。

WaitSet 主要是存放在同步块中执行 wait 方法的线程。配合 EntryList 就是 对象 的 wait 和 notify(notifyAll) 的底层实现。

参考文献:
https://tech.meituan.com/2018/11/15/java-lock.html
https://blog.csdn.net/lengxiao1993/article/details/81568130
https://cloud.tencent.com/developer/article/1036756
https://blog.csdn.net/z237794193/article/details/88426187

发布了275 篇原创文章 · 获赞 42 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_35688140/article/details/100527378
今日推荐