synchronized 锁膨胀及相关知识点

synchronized 关键字在jdk1.6之前使用的是重量级锁,在1.6之后引入自旋与锁膨胀机制,降低了性能损耗.这里以jdk1.6以后版本为前提.


CAS操作

CAS的全称为Compare And Swap,直译就是比较交换。是一条CPU的原子指令,作用就是先比较两个值是否相等,如果相等则原子的更新某个位置的值,基于硬件平台的汇编指令实现.

CAS 操作包含三个操作数 :内存偏移量位置(V),预期原值(A)和新值(B)。 如果内存位置的值与预
期原值相匹配,那么处理器会自动将该位置值更新为新值 。否则,处理器不做任何操作。

 

如图所示:

synchronized 锁膨胀及相关知识点_第1张图片

线程1去主存中读取V的值,并与自身的 A对比,结果A=V,所以将B的值更新给V,回写进主存.

线程2同理,但读取V的值发现A!=V,(线程2此次自旋失败),不做任何操作.重新去获取V的值.(线程2进入下一次自旋)

自旋

线程自旋机制中使用CAS,在自旋时不会进行线程上下文切换,减少性能损耗.


synchronized 锁的四种状态及对象头

synchronized 锁随着竞争激烈由低到高分为四种状态:无锁状态,偏向锁状态,轻量级锁状态,重量级锁状态.

对象头

synchronized 锁膨胀及相关知识点_第2张图片

四种状态下,java对象头中的Mark Word又有不同.

锁状态

25 bit

4bit

1bit

2bit

锁标志位

是否是偏向锁

23bit

2bit

GC标记

11

重量级锁

指向重量级锁Monitor的指针(依赖Mutex操作系统的互斥)

 

10

轻量级锁

指向线程栈中锁记录的指针

pointer to Lock Record

00

偏向锁

线程ID

Epoch

对象分代年龄

1

01

无锁

对象的hashCode

对象分代年龄

0

01

 

简单描述一下,当处于无锁状态时,对象头中存储的是java对象的hashCode,当出现一个线程获取这个锁时,由无锁状态升级为偏向锁,此时是否为偏向锁标识由0变为1,对象头中记录线程ID,此时如果有其他线程来获取这个对象,在竞争不激烈的情况下,可以通过自旋获取这个偏向锁,通过CAS修改对象头中的线程ID.(此处涉及到偏向锁撤销,后文会加以说明)如果竞争激烈,自旋多次都无法获取,则升级为轻量级锁,修改锁标识位,并修改对象头中的内容指向线程栈中锁记录的指针(后文加以说明).如果此时依旧无法获取到锁,则表明竞争非常剧烈,此时升级为重量级锁,修改锁标识位并阻塞当前线程.(jdk1.6之前默认为重量级锁,所以性能消耗大)

Lock Record:在线程执行同步块之前会在当前线程的栈帧中创建一个Lock Record,其中包括一个指向对象头Mark Word的指针.一个同步块对应一个Lock Record

偏向锁撤销:偏向锁使用了一种等到竞争出现才释放锁的机制,所以只有在出现线程竞争偏向锁时,持有该偏向锁的线程才会释放锁.开始偏向锁撤销时会等到原持有偏向锁的线程运行到安全点,暂停该线程,然后检查同步代码块是否执行完成如果执行完了则唤醒原持有偏向锁的线程.竞争偏向锁的线程再通过CAS去修改Mark Word中偏向锁里的线程ID.如果发现没有执行完同步代码块,则锁升级

轻量级锁:Mark Word中记录一个指向Lock Record的指针,这里就得多说一句.如图:

synchronized 锁膨胀及相关知识点_第3张图片

 Lock Record本身就会指向对象头里的Mark Word,当产生偏向锁时,Mark Word里面记录的又是指向Lock Record的指针,所以获取到轻量级锁的线程就会产生这种互相指向的模型,通过CAS修改的也是Mark Word里面记录的指针.线程中一个同步块对应一个Lock Record,而 对象头里记录哪个线程的Lock Record 意味着哪个线程获取到了轻量级锁.

重量级锁:Mark Word中记录一个指向Monitor的指针,而Monitor机制,这里也捎带说说,如图

synchronized 锁膨胀及相关知识点_第4张图片

Entry Set 存放所有阻塞的线程, The Owner 中为持有锁的线程,Wait Set 为等待状态的线程,从图中可以看出,除了持有锁的线程外,其他线程都处于阻塞状态,这里顺便提一下,wait需要组合synchronized使用,当线程处于wait状态时,会释放锁及cpu资源,所以在synchronized 同步块中wait会释放掉锁资源.

synchronized 与上文禁止重排序,但synchronized内部可以重排序

 

https://blog.csdn.net/qq_32140607/article/details/102677105

你可能感兴趣的:(多线程)