偏向锁
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操作失败,有锁线程继续按照新的锁标记释放锁,此时多线程按照重量级锁竞争。