synchronized原理及锁优化过程(简单,直白)

1.对象的组成:对象头,实例变量,填充对齐
synchronized原理及锁优化过程(简单,直白)

2,对象头的组成:Mark Word,类型指针(指向元数据区对象所属的clss对象)。Mark Word为节省存储空间,在不同场景下存储的内容不同,结构为:
synchronized原理及锁优化过程(简单,直白)
3,锁的升级过程为:
偏向锁(同步代码一直只被同一线程执行,没有其他线程竞争)----------升级----》
轻量级锁(有多个线程会执行代码,但没有冲突过) -------------------------升级----》
重量级锁(多线程同时想执行一块代码,发生冲突,等待锁的线程先自旋尝试获取锁,一直获取不到再挂起,因为挂起很耗资源)

4,不同锁对应的Mark Word结构:对照上图,
(1)偏向锁时,Mark Word直接存当前线程的id,此时锁就偏向认为只有这个线程id是我的本命线程,当线程再来获取锁时,直接看跟markWork内的线程id一样不,一样直接获取到,不一样则发现原来别的线程也想要我,就升级成轻量级锁
(2)轻量级锁,获取锁的线程,在自己的栈中分出个空间叫"lock record",然后用cas把markword的数据复制到lockrecord,再把markword的内容更新为指向lockrecord的指针,表示当前持有锁的线程
(3)重量级锁:
其实对于每个对象,都有一个monitor对象(又称管程、监视器锁)与之对应,monitor对象有两个队列,WaitSet和EntryList,有一个表示当前持有锁的字段,owner,存持有锁的线程id。可形象化为下图。持有锁的线程是owner,在中间运行,等待锁的线程在左边EntryList排队(现在可能在自旋,也可能已经被挂起)。线程运行时调wait()方法的线程被放在WaitSet队列。
synchronized原理及锁优化过程(简单,直白)
重要的来了,重量级锁的MarkWord,存的就是指向Monitor对象的指针。线程竞争重量级锁时,就是通过获取markword的monitor对象位置,再进行等待或获取锁的操作的!

上一篇:计时器方法笔记(JavaScript)


下一篇:Java对象在内存布局