synchronized的实现原理

synchronized实现同步的基础具体表现为以下三种形式:

  对于普通同步方法,锁的是当前实例对象;

  对于静态同步方法,锁的是当前类的Class对象;

  对于同步方法块,锁的是synchronized括号里配置的对象。

底层实现原理:

  synchronized实现同步主要通过monitorenter和monitorexit指令实现的;monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束和异常处,JVM要保证每个monitorenter必须有对应的monitorexit与之配对。任何对象都有一个monitor与之关联,当且一个monitor被持有后,它将处于锁定状态。线程执行到monitorenter指令时,将会尝试获取对象所对应的monitor的所有权,即尝试获得对象的锁。

  synchronized用的锁存在Java对象头里的。

    对象是数组类型,虚拟机用3个字宽存储对象头;

    对象是非数组类型,虚拟机用2个字宽存储对象头;

对象头的存储结构

锁状态 25bit 4bit 1bit是否是偏向锁 2bit锁标志位
无锁状态 对象的hashCode 对象分代年龄 0 01

  从 无锁->偏向锁->轻量级锁->重量级锁 的锁升级时,Mark Work会有不同的变化

 

 

   锁升级:

    偏向锁:适用于单线程适用的情况,在不存在锁竞争的时候进入同步方法/代码块则使用偏向锁。
    轻量级锁:适用于竞争较不激烈的情况(这和乐观锁的使用范围类似), 存在竞争时升级为轻量级锁,轻量级锁采用的是自旋锁,如果同步方法/代码块执行时间很短的话,采用轻量级锁虽然会占用cpu资源但是相对比使用重量级锁还是更高效。
    重量级锁:适用于竞争激烈的情况,如果同步方法/代码块执行时间很长,那么使用轻量级锁自旋带来的性能消耗就比使用重量级锁更严重,这时候就需要升级为重量级锁。

 

 

 

posted @ 2022-07-17 20:59  金玉良猿  阅读(377)  评论(0)    收藏  举报