首页 > 编程语言 >Java锁升级

Java锁升级

时间:2022-12-19 12:14:22浏览次数:67  
标签:Java 对象 Mark 升级 线程 自旋 Word 等待

锁升级

整体对象头 Mark Word 结构如下:
img

1. 自旋锁与自适应自旋

1.1 自旋锁

如果物理机器有一个以上的处理器或者处理器核心,能让两个或以上的线程同时并行执行,我们就可以让后面请求锁的那个线程“稍等一会”,但不放弃处理器的执行时间,看看持有锁的线程是否很快就会释放锁。为了让线程等待,我们只须让线程执行一个忙循环(自旋),这项技术就是所谓的自旋锁。

1.2 自适应自旋

自旋等待不能代替阻塞,自旋等待本身虽然避免了线程切换的开销,但它是要占用处理器时间的,所以如果锁被占用的时间很短,自旋等待的效果就会非常好,反之如果锁被占用的时间很长,那么自旋的线程只会白白消耗处理器资源,而不会做任何有价值的工作,这就会带来性能的浪费。

由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定的。如果在同一个锁对象上,自旋等待刚刚成功获得过锁,并且持有锁的线程正在运行中,那么虚拟机就会认为这次自旋也很有可能再次成功,进而允许自旋等待持续相对更长的时间。

2. 偏向锁

只会锁对象只会被一个线程使用,会使用对象哈希码的存储空间来存储线程ID,但是对象已经计算过一致性哈希码后,它就再也无法进入偏向锁状态。其他线程来使用时,会先自旋等待一会,如果锁还没释放就自旋失败升级为轻量级锁。

  • 作用:减少 check,避免 cas 带来的性能消耗,每次只对比锁对象中的线程ID。

3. 轻量级锁

不同时间错过时间来加锁。当有其他线程来参与时,先自旋等待一会,如果失败就会升级为轻量级锁,其中使用 CAS 将 Mark Word 中的存储地址会存储到线程栈帧中的 Lock record,而栈帧中会存储 Mark Word。虚拟机首先会检查对象的Mark Word是否指向当前线程的栈帧,如果是,说明当前线程已经拥有了这个对象的锁,那直接进入同步块继续执行就可以了,否则就说明这个锁对象已经被其他线程抢占了。如果出现两条以上的线程争用同一个锁的情况,那轻量级锁就不再有效,必须要膨胀为重量级锁。

4. 重量级锁

当其膨胀成重量级锁后,其他竞争的线程进来就不会自旋了,而是直接阻塞等待,并且 Mark Word 中的内容会变成一个监视器(monitor)对象,用来统一管理排队的线程。

  • EntryList:ContentionQueue 中有资格的线程会被移动到这里,相当于进行一轮初筛,进入的线程会阻塞。
  • Owner:拥有当前 monitor 对象的线程,即持有锁的那个线程。
  • WaitSet:当 Owner 线程调用 wait() 方法被阻塞之后,会被放到这里。当其被唤醒之后,会重新进入 EntryList 当中,这个集合的线程都会阻塞。

5. 整体流程如下

img

参考博客:https://juejin.cn/post/7072533669377736711#heading-3

标签:Java,对象,Mark,升级,线程,自旋,Word,等待
From: https://www.cnblogs.com/theheboy/p/16991825.html

相关文章

  • 连号区间数【第四届蓝桥杯省赛C++B组,第四届蓝桥杯省赛JAVAB组】
    连号区间数小明这些天一直在思考这样一个奇怪而有趣的问题:在\(1∼N\)的某个排列中有多少个连号区间呢?这里所说的连号区间的定义是:如果区间\([L,R]\)里的所有元素(即......
  • kubernetes 1.21 版本升级
    1.规划升级前:组件名称位置版本kube-apiserver/usr/bin/kube-apiserverv1.21.13etcd、etcdctl/usr/bin/etcd、/usr/bin/etcdctl3.5.4kube-controll......
  • java核心技术学习笔记——synchronized底层如何实现?什么是锁的升级、降级?
    在Java6之前,Monitor的实现完全是依靠操作系统内部的互斥锁,因为需要进行用户态到内核态的切换,所以同步操作是一个无差别的重量级操作。现代的(Oracle)JDK中,VM对此进......
  • javaMail笔记
    JavaMail        javaMail是提供给开发人员在应用程序中实现邮件发送和接收功能而提供的一套表中开发类库,支持常用的邮件协议,如SMTP,POO3,IMAP,开发人员使用javaMa......
  • 【java】(二) SpringBoot 源码解析——run启动加载过程——准备环境
    1.前言深入学习springboot笔记系列,可能会有错误还请指正,互相勉励,互相学习。上一章讲了SpringApplicaiton是如何初始化的,本章讲解后续的run方法的启动过程。本章涉及......
  • Java实现基本的HTTP/HTTPS请求 - 包含协议头
    importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.OutputStream;importja......
  • java.exe进程来源排查录
     解决后的一个小结:此处是一个tomcat端口,这种情况下,可以先在浏览器访问下看看效果,就可以快速定位 又发现一个简单的办法:  下面的定位过程,适用于各种场合  无意中发现有......
  • Java如何实现自定义异常
    自定义异常概述为什么需要自定义异常类:我们说了Java中不同的异常类,分别表示着某一种具体的异常情况,那么在开发中总是有些异常情况是SUN没有定义好的,此时我们根据自己......
  • Java大写字母转换成小写字母(转载)
    问题:把一个小写字母转对应的大写字母,有几种办法?解题思路1:使用语言自带的APIpublicCharactertoLowerCase(Characters){returnCharacter.toLowerCase(s);......
  • 教你用JavaScript实现推荐滑块
    案例介绍欢迎来到我的小院,我是霍大侠,恭喜你今天又要进步一点点了!我们来用JavaScript编程实战案例,做一个推荐滑块。推荐滑块展示内容,每隔3秒自动变换。案例演示运行程序后......