
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
线程安全问题随着互联网的不断发展而被越来越多的程序员关注,而本文我们就通过案例分析来简单了解一下,线程安全锁的优化都有哪些方法。
1、CAS自旋
CAS:CompareAndSwap对比然后交换值,CAS属于硬件指令级别,因此本身可以保证原子性。
自旋:CAS操作中会有个期望值的限制,达不到这个预期,则执行不成功。因此期望终能够执行,则需要多次尝试,也就是所谓的“自旋”,循环尝试。
例如,对于普通的“++”操作,是非线程安全的,而要达到线程安全的+1目的,就必须添加必要的同步性保障,或者,使用此处我们所论述的CAS特性。
示例:AtomicInteger::getAndIncrement
内部通过Unsafe实例的compareAndSwapInt方法实现。
2、轻量锁
单一线程访问加锁优化;对象头信息MarkWord;前提---对于绝大多数锁,在整个同步周期内是不存在竞争的;无竞争情况下,使用CAS操作消除同步使用的互斥量。
执行过程:
进入同步块,对象未加锁(锁标志位01)
线程栈帧中建立一个锁记录(LockRecord)空间(存储锁对象MarkWord拷贝:DisplacedMarkWord)
虚拟机尝试使用CAS操作,将对象的MarkWord更新为指向LockReord的指针
更新成功,线程拥有对象锁,对象MarkWord锁标志位变为00
更新失败,则检查对象MarkWord是否指向当前线程
是的话,则说明已经拥有了轻量级锁,继续同步块操作
否的话,则说明对象已经被其它线程占有,两个及以上线程征用同一个锁,则膨胀为重量级锁,所标志位变为10,MarkWord存储的是指向重量级锁()的指针
解锁:CAS将线程的复制的DisplaceMarkWord和对象的MarkWorld替换回来。
3、偏向锁
无竞争情况下,消除整个同步块。偏向于一个获得锁的线程。
对象锁一次被线程获取的时候,虚拟机把对象头的标志位设为01,偏向模式,同时使用CAS模式把获取到这个锁的线程ID写入对象的MarkWord中
获取锁成功,持有偏向锁的线程每次进入锁的相关同步块,虚拟机都可以不再进行任何同步操作。
另外线程尝试获取此所,则偏向模式结束,撤下偏向(RevokeBias),恢复未锁定(00)或者轻量级锁定(10)。
4、锁粗化
选择合适的粒度层级进行加锁同步。
5、锁消除
如果一段代码中,堆上的所有数据都不会逃逸出去而被其它线程访问到(逃逸分析),当作栈上数据对待,消除锁。
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请加抖音太原达内IT培训学习了解。