JAVA Synchronized关键词 原理解析

偏向锁

每次获取锁和释放锁让费资源,然而在很多情况下,竞争锁不是由多个线程,而是由一个线程在使用。回去看锁标志位是不是偏向锁,如果是,看线程ID是否一致。如果是的话,就没有锁获取锁释放的操作。适用一个线程访问同步代码块的时候。

对象头会存储

Mark Word,class metadata, array length

Mark Word 里在对象没有被锁住的时候会存储,线程id; epoch; 对象的分代年龄信息; 是否是偏向锁;锁标志位。

如下图:


JAVA Synchronized关键词 原理解析_第1张图片

轻量级锁,同时让我们的多个线程进入到代码块中,JVM会在当前线程的栈帧中存储锁记录的空间,然后将对象头的MARK WORD 复制到锁记录中,随后原先的MARK WORD会变成指向锁记录的指针了。MARK WORD这边锁标志位就改成轻量级锁。如下图:


JAVA Synchronized关键词 原理解析_第2张图片


JAVA Synchronized关键词 原理解析_第3张图片

轻量级锁能提高程序同步性能的依据是“对于绝大部分的锁,在整个同步周期内都是不存在竞争的”,这是一个经验数据。如果没有竞争,轻量级锁使用CAS操作避免了使用互斥量的开销,但如果存在锁竞争,除了互斥量的开销外,还额外发生了CAS操作,因此在有竞争的情况下,轻量级锁会比传统的重量级锁更慢。


JAVA Synchronized关键词 原理解析_第4张图片

首先JVM 会优先去为这个OBJECT申请偏向锁,具体方法就是去查看对象头里面是否已经有偏向锁标志,然后把当前申请锁的线程ID存进去。

如果发现这个OBJECT对象头里已经有别的线程ID使用了偏向锁,并且没有释放。那么JVM会升级偏向锁为轻量级锁。

轻量级锁的原理是在执行同步块前,JVM会先在当前线程的栈帧中创建用于存储锁记录的空间。然后线程尝试使用CAS将对象头的MARK WORK替换为指向锁记录的指针,如果替换成功,则拿到轻量级锁。解锁时,会使用CAS操作将DISPACED MARK WORD 替换回对象头,如果成功,表示没有竞争。如果失败,升级为重量级锁。

重量级锁就是用操作系统的互斥量来实现,需要挂起线程。


你可能感兴趣的:(JAVA Synchronized关键词 原理解析)