Java虚拟机层面的几种锁

1.  偏向锁

当一个锁被线程获取后,这个线程便进入偏向模式,当线程再次请求这个锁时,无需再进行相关的同步操作,从而节省了时间。如果在此之前,其他线程进行了锁请求,则原线程退出偏向模式。当对象处于偏向模式时,对象头的Mark Word会记录获取锁的线程

JavaThread*  |  epoch  | age  | 1  | 01

这样,当该线程再次尝试获取该对象锁时,通过Mark Word的线程信息就可以判断当前线程是否持有偏向锁。

但是注意: 偏向锁在竞争激烈的场合没有太强的优化效果,因为大量的竞争会导致持有锁的线程不停的切换,锁也很难一直保持在偏向模式,此时,使用偏向锁不仅不能得到性能优化,反而可能降低性能。因为,在竞争激烈的场合,可以尝试使用-XX:-UseBiasedLocking参数禁用偏向锁


2. 轻量级锁

如果尝试申请偏向锁失败,则Java虚拟机会让线程申请轻量级锁。使用的CAS操作,尝试将BasicLock的地址复制到对象头的Mark Word,如果复制成功,那么加锁成功,否则认为加锁失败。如果加锁失败,轻量级锁就有可能被膨胀为重量级锁。

轻量级锁在虚拟机内部,使用一个称为BasicObjectLock的对象实现,这个对象内部由一个BasicLock对象和一个持有该锁的Java对象指针组成。BasicObjectLock对象放置在Java栈的栈帧中。当要判断某一线程是否持有该对象锁时,也只需简单的判断对象头的指针是否在当前线程的栈地址范围内即可


3.  重量级锁

4. 自旋锁

自旋锁可以使线程在没有取得锁时不被挂起,转而去执行一个空循环(所谓的自旋),在若干个空循环后,线程如果可以获得锁,则继续执行。若线程仍然不能获得锁,才会被挂起。对于那些锁竞争不是很激烈,锁占用时间很短的并发线程,具有一定的意义,但是对于锁紧张激烈,单线程锁占用时间长的并发程序,自旋锁在自旋等待后,往往依然无法获得对应的锁,不仅浪费了时间,最终还是会被挂起,浪费了资源


5. 锁消除

锁消除是Java虚拟机在JIT编译时,通过对运行上下文的扫描,去除不可能存在共享资源竞争的锁。从而消除毫无意义的请求锁时间。

这主要是针对比如StringBuffer,Vector一些线程安全的工具类使用在了本身不存在竞争的场合。虚拟机可以在运行时,基于逃逸分析技术,捕获到这些不可能存在竞争却又申请锁的代码段,并消除这些不必要的锁,提供系统性能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值