Java synchronized锁的底层实现概述

偏向锁

JVM默认开启偏向锁。在对象头中锁标志前一位用来标记偏向锁是否可用。
锁标记01表示偏向锁。

偏向锁释放

获得偏向锁的线程,在对象头中写有线程id,不会主动释放锁:

  • 没有其他线程竞争,对象头中始终是获得锁的tid。
  • 线程tid2竞争,此时objhead中仍存着tid1。JVM首先安全暂停tid1,判断tid1是否仍处于同步块,如果是,那么需要升级锁;如果不是,说明tid1不需要锁了,objhead中的tid字段置零——释放锁。线程可以再次竞争偏向锁。

偏向锁就是这个意思,偏向已经获取到锁的线程,默认不释放,只有竞争发生时,才有释放锁的可能,如果此时仍然需要锁定,那么竞争失败,可以认定线程竞争比较频繁,因此,需要升级锁。

CAS

CAS是获取锁的关键操作,大概是boolean CAS(objhead.tid,markword,selftid_markword)这样的方法,其中markword是未加锁状态的markword,主要是测试锁标记为01时,objhead是否无锁(tid==0),如果是,则设置自己的tid,表明加锁。
锁的本质是一个状态量,竞争锁的关键点在于检查状态和设置状态是原子完成的。

轻量级锁

自旋5000次

占用锁的线程在同步代码结束后,使用cas释放锁,当有竞争时,此时的锁标记已经被竞争者修改为重量级锁10,cas操作失败,有锁线程继续按照新的锁标记释放锁,此时多线程按照重量级锁竞争。

重量级锁

使用OS的Mutex Lock

posted on 2018-05-02 21:24  还好可以改名字  阅读(1634)  评论(0编辑  收藏  举报