synchronized的锁升级过程

2023-05-16

synchronized的锁升级过程 : 

锁的状态总共有四种,级别由低到高依次为:无锁、偏向锁、轻量级锁、重量级锁

在 JDK 1.6之前,synchronized 还是一个重量级锁,是一个效率比较低下的锁,但是在JDK 1.6后,Jvm为了提高锁的获取与释放效率对(synchronized )进行了优化,引入了 偏向锁 和 轻量级锁 ,从此以后锁的状态就有了四种(无锁、偏向锁、轻量级锁、重量级锁),并且四种状态会随着竞争的情况逐渐升级,而且是不可逆的过程,即不可降级,也就是说只能进行锁升级

synchronized加锁锁的对象就是说在对象头中修改mark word的信息来实现的加锁,谁修改成功谁获得锁

上图中,如果对象最后2bit是00代表轻量级锁,如果是10代表重量级锁,11代表这个对象正在被GC回收,01有二种状态,再01的前提下,看倒数第三位0代表无锁,1代表是偏向锁

偏向锁和轻量级锁都是用户态级别的锁,不需要经过系统调用的过程,所以效率会高

偏向锁: 再执行的过程中只有一个线程执行,没有发生锁的竞争,直接将线程指针写入到对象的markeword中

当又来了一个线程(发生了竞争),会将偏向锁撤销,然后进行竞争,每个线程都有自己的线程栈,每个人再自己的线程内部生成LR(锁记录),然后用自旋的方式将自己的lr指针写入到对象的markeword中,当对象markword中指向了那个线程的lr,那个线程争抢成功,另一个线程会继续cas的去竞争,当竞争成功的线程执行完了,这个线程继续执行,这个时候就是轻量级锁

重量级锁; 发生竞争但是在自旋过程中依然没有获取到锁就会升级重量级锁,这种锁  需要经过一次系统调用,要上操作系统申请

为什么有自旋还需要重量级呢? 因为自旋是需要消耗cpu资源的 自旋时间太长会浪费cpu资源 重量级锁有等待队列,将线程放入等待队列,不需要消耗cpu资源

自旋几次呢?  默认是10次(可以设置)或者自旋线程数超过了cpu核数的一半,但是在jdk1.6进行了优化,自旋次数变成了自适应的,所以不用去设置

jvm再启动过程中,会有很多线程启动,所以jvm刚启动的时候,偏向锁不会打开,这时候创建的对象加锁会直接进入轻量级锁, 默认时间4秒后启动 可以设置 参数可以百度一下

刚new的对象如果偏向锁没有启动,就是普通对象,如果偏向锁启动就是匿名偏向锁

匿名偏向锁: 当偏向锁启动后才new的对象,但是没有线程去更改这个对象的markeword,所以线程指针为null, 这就叫匿名偏向锁

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

synchronized的锁升级过程 的相关文章

  • synchronized对于加锁代码块、方法以及全局(static)锁的详细对比

    在网上看了许多关于synchronized的介绍及用法区别 大多大同小异 点到为止 个人推荐一篇博友写的 网址如下 http blog csdn net cs408 article details 48930803 这篇博客是介绍对象锁和类
  • Java中synchronized同步锁用法及作用范围

    Java 中的 synchronized 关键字可以在多线程环境下用来作为线程安全的同步锁 本文主要对 synchronized 的作用 以及其有效范围进行讨论 Java中的对象锁和类锁 java的对象锁和类锁在锁的概念上基本上和内置锁是一
  • 详解Java锁对象

    1 Synchronized 1 1 synchronized特性 1 互斥 synchronized会起到互斥效果 某个线程执行到某个对象的synchronized中时 其他线程如果也执行到同一个对象synchronized就会阻塞等待
  • 并发编程 三 synchronized

    多线程编程中 有可能会出现多个线程同时访问同一个共享 可变资源的情况 这个资源我们称之其为临界资源 这种资源可能是 对象 变量 文件等 由于线程执行的过程是不可控的 所以需要采用同步机制来协同对对象可变状态的访问 实际上 所有的并发模式在解
  • 悲观锁synchronized、乐观锁CAS

    1 悲观锁 乐观锁 悲观锁是一种思想 在多线程竞争下 加锁 释放锁会导致比较多的上下文切换和调度延时 引起性能问题 一个线程持有锁会导致其它所有需要此锁的线程挂起 如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置 引起性能
  • synchronized、volatile底层原理详解

    文章目录 一 synchronized 1 监视器Monitor monitor结构及原理 监视器Monitor有两种同步方式 互斥与协作 2 Mutex lock mutex的工作方式 3 java对象头 java对象布局 4 无锁 偏向
  • Java多线程编程基础篇(二)-多线程同步关键字

    一 多线程同步关键字 synchronized 1 概念 synchronized保证方法或者代码块在运行时 同一时刻只有一个方法可以进入到临界区 同时它还可以保证共享变量的内存可见性 当多个并发线程访问同一个对象object中的同步代码块
  • Java的notify()在wait()之前运行?

    public class ThreadA public static void main String args ThreadB b new ThreadB b start synchronized b try System out pri
  • 使用什么原语来实现同步关键字?

    当我们使用synchronizedjava中的关键字 究竟使用哪个同步原语 Lock Semaphore Monitor Mutex EDIT JVM如何在本机级别实现锁 在字节码级别 java有monitorenter and monit
  • 同步单例的正确使用?

    所以我正在考虑建立一个业余爱好项目 这是一种临时性的事情 只是为了温习我的编程 设计 它基本上是一个多线程网络蜘蛛 更新相同的数据结构object gt int 因此 为此使用数据库绝对是大材小用 我唯一能想到的是用于包含我的数据结构的线程
  • Java 同步方法...不同步

    对于我当前的 java 练习 我必须从 2 个不同的 Gmail 帐户获取邮件 我通过创建 Gmail 类的新实例来完成此操作 gmail 类扩展了线程 其中有一个同步方法 readMail 用于获取邮件并打印它 这个 readMail 方
  • 在函数中通过类名同步是否在扩展类中有效?

    我在基类中有一个方法 foo 使用 Synchronized 类名 以及扩展基类的两个类 A 和 B 如果我在两个不同的线程中从 A 实例和 B 实例调用 foo 它们会同步吗 这是一个示例代码 class BaseClass void f
  • 为什么同步字段变量并在同步块内递增它会导致打印乱序?

    我有一个简单的代码片段 public class ItemManager private Integer itemCount 0 public void incrementAndPrint synchronized this System
  • 当锁持有非最终对象时,该对象的引用是否仍然可以被另一个线程更改?

    当一个对象需要同步时 如果它没有设置为非最终的 IDE 会抱怨 因为它的引用不是持久的 private static Object myTable synchronized myTable IDE complains access myTa
  • 如何检查对象是否正在@synchronized

    有时我会编写以下代码来同步例程 synchronized objToBeSync 当两个线程尝试同时访问同步块时 其中一个线程会阻塞其他线程 直到其中一个线程退出同步块 但是 有时我不希望一个对象阻塞另一个对象 但其他对象检查对象是否正在同
  • 如何正确使用同步链接哈希图

    尝试通过子类化链接哈希映射来制作 lru 映射 地图通过 collections synchronized 运行 映射的所有用法都被同步块包围 如果它们全部被删除 单元测试也会失败 人们可能会认为它们是不必要的 因为地图是通过 collec
  • Java中有同步队列吗? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 有同步的吗QueueJava 中的类
  • 同步与 ReadWriteLock 性能

    我试图证明当有很多读者而只有一些作者时同步会更慢 不知怎的 我证明了相反的情况 以 RW 为例 执行时间为 313 ms package zad3readWriteLockPerformance import java util Array
  • 如何使用 wait() 和 notification() 正确暂停线程

    我想要一个启动线程并提供暂停和继续该线程的方法的类 我的第一个方法是使用标志 只要该值为 true 它就会循环 sleep 方法 就像是 public class Bot private Thread t private boolean i
  • 在java中以原子方式获取多个锁

    我有以下代码 注意 为了可读性 我尽可能简化了代码 如果我忘记了任何关键部分 请告诉我 public class User private Relations relations public User relations new Rela

随机推荐