线程安全与锁优化

乐观锁: cas aba
版本号(AtomicStampedReference)
时间戳
AtomicMarkableReference(boolean)
可重入代码:绝对线程安全,不依赖共享数据(使用参数,局部变量)

自旋锁:认为锁很快释放,占用cpu循环获取锁,超过一定次数(时间)再挂起线程,自旋次数上限-XX:PreBlockSpin,启用自旋-XX:+UseSpinning(1.6后默认开启)
自适应自旋:自旋次数上限不再固定,根据监控数据自旋容易成功那就长点,不容易就短点甚至不自旋
锁消除:jit根据线程逃逸分析去除同步
锁粗化:连续小范围的同一把锁的加解锁进行扩大

线程安全与锁优化

可偏向和无锁锁标志都是01,通过偏向锁标记来区分
偏向锁:消除数据在无竞争下的同步原语,-XX:+UseBiasedLocking(1.6后默认)
可偏向(01,1)有三种小状态:
可偏向但未偏向(threadID=0),已偏向(加锁或未加锁状态,是否处于加锁状态只能看线程是否处于同步代码块内)
对于owner线程以后的加锁解锁只需要test一下是自己,不做任何修改操作(解锁后自己还是那个偏向线程)
其他线程加锁:偏向线程已不存在,重偏向(threadID设为0,然后cas改为自己)
偏向线程还存在:撤销偏向(过程中需稍微暂停唤醒原线程)
1原线程已退出同步块,恢复为无锁模式
2 原线程在同步块内,恢复为轻量级锁定模式

轻量级锁定:重量级锁定(操作系统互斥量,性能消耗大),考虑在无竞争下(若开启自旋,可认为存在轻微竞争)使用cas就好,轻量级锁定下一定不会有线程阻塞(可能有自旋)

加锁过程:当前线程栈帧创建Lock Record(存放Displaced Mark Word,即原始的Mark Word),cas将Mark Word 更新为指向Lock Record的指针
更新失败(过程中其他线程抢先cas了)或后续其他线程更新失败(若mark word是01无锁,更新为指向自己的轻量级锁定),说明对象已加锁,若开启了自旋,则自旋cas尝试加锁,自旋到上限或未开启自旋,膨胀为重量级锁定,线程阻塞

解锁过程:cas将Displaced Mark Word替换到Mark Word内,cas失败(其他线程尝试加锁导致膨胀为重量级锁定,Mark Word 已经改变了)不仅要释放锁还要唤醒挂起线程