synchronized同步的位置:
1、普通同步方法,锁是当前实例对象;
2、静态同步方法,锁是当前类的class对象;
3、同步方法块,锁是括号里面的对象。
synchronized存于Java对象头中
虚拟机的对象头主要包括两部分数据:Mark Word(标记字段)、Klass Pointer(类型指针)。
Mark Word:存储对象自身的运行时数据
例如:哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等等

当Java对象头的Mark Word发生锁升级时,非固定长度的Mark Word数据结构也会发生改变

Klass Point:对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
Java对象头储存结构:
synchronized的同步机制Monitor
每一个Java对象出生自带Monitor锁,所以每个Java对象都可以成为Monitor
在线程中,Monitor时线程私有的数据结构
每一个线程都会有一个可用的monitor record列表和一个全局的可用列表,将被加锁对象与monitor锁关联**(对象头的MarkWord中的LockWord指向monitor的起始地址)**,同时monitor锁中存放该线程的唯一标识id,以表示该锁被某个线程占用,以此实现同步机制
Monitor列表结构

Owner:初始时为NULL表示当前没有任何线程拥有该monitor record,当线程成功拥有该锁后保存线程唯一标识,当锁被释放时又设置为NULL。
EntryQ:关联一个系统互斥锁(semaphore),阻塞所有试图锁住monitor record失败的线程。
RcThis:表示blocked或waiting在该monitor record上的所有线程的个数。
Nest:用来实现重入锁的计数。HashCode:保存从对象头拷贝过来的HashCode值(可能还包含GC age)。
Candidate:用来避免不必要的阻塞或等待线程唤醒,因为每一次只有一个线程能够成功拥有锁,如果每次前一个释放锁的线程唤醒所有正在阻塞或等待的线程,会引起不必要的上下文切换(从阻塞到就绪然后因为竞争锁失败又被阻塞)从而导致性能严重下降。
Candidate只有两种可能的值0表示没有需要唤醒的线程1表示要唤醒一个继任线程来竞争锁。
本文详细探讨了Java中的synchronized同步位置,包括普通同步方法、静态同步方法和同步方法块。同时深入解析了Java对象头的Mark Word和Klass Pointer,特别是Mark Word在锁状态变化时的角色。此外,文章还介绍了Monitor锁作为线程私有数据结构的工作原理,包括Owner、EntryQ、RcThis、Nest和Candidate等组件在同步机制中的作用。
9万+

被折叠的 条评论
为什么被折叠?



