
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
锁的应用在许多软件编程开发项目中都是会经常用到的一个编程功能,而本文我们就通过案例分析来简单了解一下,Java编程偏向锁与轻量级锁的应用分析。
一、偏向锁
偏向锁的来历是这么一回事:Hotspot,也就是目前应用广泛的Java虚拟机的作者发现:绝大多数情况下,锁不仅不存在竞争,而且总是由同一线程多次重复获得。在这种情况下,反复获取锁再解锁就非常影响效率,所以引入了偏向锁这种超轻量级的锁。
偏向锁的锁机制
当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,此后该线程进入和退出同步块时就可以免于加锁去锁了,只需要检查一下对象头中的MarkWord里是否存储着指向当前线程的偏向锁即可。若成功即表明已经获取锁,若失败则要检查偏向锁标识是否为1,如果失败则需要竞争锁,如果成功则将对象头中的偏向锁指向当前线程。
偏向锁的撤销
同时,偏向锁使用了一种仅当竞争出现才释放锁的机制,当其他线程尝试竞争偏向锁时,持有偏向锁的线程才会释放锁。这个操作需要等到全局安全点(该时间点上没有正在执行的字节码文件)才会执行,它先会暂停拥有偏向锁的线程,并检查其是否存活,若不处于活动状态则直接将对象头设置为无锁状态。若存活则拥有偏向锁的栈会被执行,遍历偏向对象的锁记录,栈中的锁记录和对象头的偏向锁要么重新偏向其他线程,要么恢复无锁或标记为不适合作为偏向锁。后唤醒暂停的线程。
偏向锁设置
偏向锁是默认启用的,但是它在应用程序启动后延迟数秒才会激活。
若你能确定,程序中所有的锁通常情况下皆处于竞争状态,则可以取消偏向锁,使得所有锁都默认直接进入轻量级锁状态。
二、轻量级锁
轻量级锁加锁机制
轻量级锁的加锁机制简单来讲就是:
线程中开辟一个存储锁记录的空间,然后将对象头中的MarkWord复制到锁记录中
尝试通过CAS操作,将对象头中的MarkWord换成指向锁记录的指针
若成功,则获得锁;而如果此CAS操作失败,即表示竞争发生,尝试自旋获取锁
轻量级锁解锁机制
解锁时,我们要有借有还,线程会尝试通过CAS操作将存在栈帧锁记录中的MarkWord文本写回对象头中,如果此操作成功,即说明没有发生竞争,成功解锁。若CAS操作失败,证明存在竞争,该锁就会膨胀为重量级锁。
采取这种策略需要结合其加锁机制,轻量级锁如果尝试获取锁没成功就会一直自旋尝试获取,而自旋是占用CPU的,所以为了避免影响CPU效率,一旦持有锁的线程释放锁时发现存在竞争,就会使得该锁膨胀为重量级锁。
此时所有自旋尝试获取锁的线程会被阻塞,仅能由持有锁的线程释放锁后再将等待线程全部唤醒,再进行锁的竞争。
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!更多内容请加danei456学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。