JAVA synchronized锁升级

JAVA synchronized锁升级

提示

年轻人不讲理论

锁升级

无锁 → 偏向锁 → 轻量级锁 → 重量级锁

伪代码

//伪代码
class A{
    
    
    synchronize  hello(){
    
    
           hi();
    }
    synchronize hi(){
    
    
           sout("hi")
    }
    main(){
    
    
    
       A a = new A();
       new Thread( a.hello(), "1线程").start;
       new Thread( a.hello(), "2线程").start;
       new Thread( a.hello(), "3线程").start;
       new Thread( a.hello(), "4线程").start;

    }
}

锁升级过程

最复杂情况下:

  • 1线程调用a对象hello方法,需要锁住a对象,查看a对象头存储的锁状态为无锁,将锁状态改为偏向锁,a对象头中设置正在运行的线程id为1线程的id

  • 1线程调用hi方法,需要锁住a对象,查看对象头锁状态为偏向锁,拥有锁的线程id和自己线程id一致,不需要抢夺锁

  • 1线程调用未结束

  • 2线程调用a对象hello方法,需要锁住a对象,查看a对象头存储的锁状态为偏向锁,将锁状态改为轻量级锁,2线程做CAS自旋,循环获取锁

  • 3线程调用a对象hello方法,需要锁住a对象,查看a对象头存储的锁状态为轻量级锁,3线程直接做CAS自旋,循环获取锁

  • 2,3线程循环时间达到阈值,或者多个线程都在此自旋(自旋浪费cpu),将a对象头中的锁状态改为重量级锁

  • 2,3线程查看a对象头锁状态为重量级锁,直接将线程放入a对象头中的线程等待队列,不再自旋

  • 4线程调用a对象hello方法,需要锁住a对象,查看a对象头存储的锁状态为重量级锁,直接进入等待队列

  • 1线程调用hi结束

  • 1线程调用hello结束

  • 1线程唤醒其它等待线程

  • 等待线程抢夺锁

猜你喜欢

转载自blog.csdn.net/GOGO_912/article/details/115410567