简单理解重量级锁、轻量级锁、偏向锁

article/2025/10/21 13:07:07

全文使用synchronized来说明。
synchronized给对象上锁,先上偏向锁,在上轻量级锁,最后上重量级锁。上什么锁,是jvm根据竞争程度自行变换的。

重量级锁

计算机操作系统本有Monitor对象,称为管程。在java里面看不到此对象。
每个Java对象都可以关联一个monitor对象,如果使用了synchronized给对象上重量级锁后,该对象的Mark word就被设置指向monitor对象的指针。

Monitor对象结构

在这里插入图片描述

  • WaitSet:是线程等待队列。状态为WAITING
  • EntryList:线程阻塞队列.状态为BLOCKED
  • Owner:正在执行的线程(可能很多线程竞争一个资源,但只有一个线程能够成功,此时Owner就置为此线程)

原理

  1. 新建的对象,此时Mark Word关联一个Monitor对象(即Mark Word记录一个monitor对象的地址)。此时Monitor对象里面的Owner为null.
    因为还没有线程去获得Monitor锁。
    在这里插入图片描述
  2. 多个线程竞争,只有线程1成功。其他进入阻塞队列。(或者说,只要owner非空,那么其他线程就要进入阻塞队列)
    当线程1执行完毕后,通知阻塞队列里的线程,引起它们的非公平性竞争。
    在这里插入图片描述
  3. 若此时Owner线程调用wait方法,那么会进入WaitSet。
    当被唤醒时(如调用notify())会进入EntryList重新竞争。

轻量级锁

如果一个对象虽然有多线程访问,但多线程访问的时间是错开的(或者说没有竞争)的话,可以使用轻量级锁来优化。
当有竞争时,会发生锁膨胀,变为重量级锁,

java 对象头

以32为虚拟机为例
普通对象是:
在这里插入图片描述

  • Klass Word:是一个指针,通过他可以知道是个啥类对象
  • Mark Word:
    在这里插入图片描述
    如 Normal ,即没有上锁,末尾两位是01;轻量级锁是00
    下面用Hashcode age Bias 01 代替最初的Mark Word

原理

在这里插入图片描述
每个线程的栈帧都会包含一个锁记录的结构,内部可以保存锁对象的Mark Word


  • 当线程执行到临界区代码时,对obj上锁。让锁记录中的Object reference 指向锁对象,并尝试用cas替换Object的Mark Word,将 Mark Word的值存入锁记录。
    • cas替换成功:那么Object对象就会存储锁记录状态00和地址 ,表示由该线程给对象加锁。 当Mark Word末尾是01时,才可以替换成功
      在这里插入图片描述

    • cas替换失败

      • case 1:其他线程已经持有了改Object的轻量级锁,表明有竞争,进入锁膨胀过程
      • case 2:自己执行synchronized锁重入,再添加一条Lock Record作为重入的计数
        在这里插入图片描述
        此时进行cas操作自然会失败。
        最后再讲锁膨胀。
    • 解锁

      • 当Lock Record 记录里面存在null,说明存在重进入,这时重置锁记录,表示重进入计数减一
      • 锁记录不为空,这时用cas操作把锁记录里面保存的Mark Word替换给对象头
        • 成功则解锁成功
        • 失败说明进行了锁膨胀或已经升级为重量级锁,进入重量级锁的解锁流程。

锁膨胀

在尝试加轻量级锁的过程中,CAS操作无法成功,一个原因就是有其他线程为此对象加上了轻量级锁,这时需要进行锁膨胀,将轻量级锁变为重量级锁。
如线程1持有object的锁,这时线程2也想要,但进行cas操作失败,这时候会发生:

  • 为object对象申请Monitor锁,让object指向重量级锁地址(此时后两位为10,即重量级锁)
  • 然后线程2进入Monitor的EntryList阻塞
    在这里插入图片描述
    当线程1执行完后,想要退出临界区,使用cas将Mark Word的值替换给对象头,但是会失败。因为object的Mark Word后两位变为10,已经不再是00了。
    这时按照Monitor地址找到monitor对象,设置Owner为null,再唤醒线程2.

偏向锁

如果只有一个线程,它多次重进入,那会多次建立空的锁记录,作为锁重入的计数。
因此,java 6中引入了偏向锁来做进一步优化:只有第一次使用CAS将线程ID设置到对象的Mark Word,之后只要发现这个线程ID是自己的就表示没有发生竞争,不用重新CAS。以后只要不发生竞争,这个对象就归该线程所有。
当线程请求到锁对象后,将锁对象的状态标志位改为01,即偏向模式。然后使用CAS操作将线程的ID记录在锁对象的Mark Word中。以后该线程可以直接进入同步块,连CAS操作都不需要。但是,一旦有第二条线程需要竞争锁,那么偏向模式立即结束,进入轻量级锁的状态。
在这里插入图片描述

在这里插入图片描述

参考:https://www.bilibili.com/video/BV16J411h7Rd?from=search&seid=659615821890387531


http://chatgpt.dhexx.cn/article/ST1Yynck.shtml

相关文章

synchronized锁升级之偏向锁

目录 一、什么是偏向锁? 二、偏向锁原理 三、偏向锁演示 四、偏向锁的处理流程 五、偏向锁的撤销 六、偏向锁的好处 一、什么是偏向锁? HotSpot作者经过研究实践发现,在大多数情况下,锁不仅不存在多线程竞争,而…

Java无锁、偏向锁、轻量级锁、重量级锁,锁升级过程

2. 锁 2.1 无锁 Java对象刚创建时还没有任何线程来竞争,说明该对象处于无锁状态(无线程竞争它),这时偏向锁标识位是0,锁状态是01 。 2.2 偏向锁 偏向锁是指一段同步代码一直被同一个线程所访问,那么该…

偏向锁的获取和撤销详解

Java SE 1.6 为了减少获得锁和释放锁带来的性能消耗,引入了偏向锁和轻量级锁;在Java SE 1.6 中,锁共有4种状态,级别从底到高依次是:无锁状态、偏向锁状态、轻量级锁和重量级锁状态,这几种状态会随着竞争情况…

一篇文章说清 :无锁、偏向锁、轻量级锁、重量级锁

文章目录 前言一、无锁二、偏向锁三、轻量级锁(自选锁)四、重量级锁锁升级场景 前言 JDK1.6为了减少获得锁和释放锁所带来的性能消耗,引入了“偏向锁”和“轻量级锁”,所以在JDK1.6里锁一共有四种状态,无锁状态&#x…

synchronized的偏向锁、轻量级锁和重量级锁

文章目录 Java对象头偏向锁批量重偏向批量撤销 轻量级锁重量级锁Monitor 原理 Java对象头 普通对象 Mark Word在64 位虚拟机中的结构为 Mark Word后三(两)位表示 001:无锁状态101: 偏向锁00: 轻量级锁10&#xff1a…

Java synchronized偏向锁、轻量级锁、重量级锁

简介 synchronized锁共有偏向锁、轻量级锁、重量级锁三种类型,而这三种类型的加锁方式都是相同的,写代码时不用考虑加哪种锁。使用锁时对象首先会变为偏向锁状态,当有其它线程获取锁时会升级为轻量级锁(没有竞争锁)&am…

java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁

之前做过一个测试,详情见这篇文章《多线程 1操作的几种实现方式,及效率对比》,当时对这个测试结果很疑惑,反复执行过多次,发现结果是一样的: 1. 单线程下synchronized效率最高(当时感觉它的效率应该是最差…

偏向锁、轻量级锁、重量级锁的区别和解析

为了换取性能,JVM在内置锁上做了非常多的优化,膨胀式的锁分配策略就是其一。理解偏向锁、轻量级锁、重量级锁的要解决的基本问题,几种锁的分配和膨胀过程,有助于编写并优化基于锁的并发程序。 内置锁的分配和膨胀过程较为复杂&…

偏向锁是什么

偏向锁操作流程偏向锁,顾名思义,它会偏向于第一个访问锁的线程,如果在接下来的运行过程中,该锁没有被其他的线程访问,则持有偏向锁的线程将永远不需要触发同步 但是从我们跑的代码输出却看不到偏向锁这个东东。为啥对…

偏向锁的基本原理

偏向锁的基本原理 前面说过,大部分情况下,锁不仅仅不存在多线程竞争,而是总是由同一个线程多次获得,为了让线程获取锁的代价更低就引入了偏向锁的概念。怎么理解偏向锁呢?当一个线程访问加了同步锁的代码块时&#xff…

偏向锁,轻量级锁,重量级锁的核心原理

前言:大家好,我是小威,24届毕业生,在一家满意的公司实习。本篇文章是关于并发编程中偏向锁,轻量级锁,重量级锁的核心原理知识记录。 本篇文章记录的基础知识,适合在学Java的小白,也适…

深入探究synchronize锁机制

synchronized 有三种方式来加锁,分别是: **1. 修饰实例方法:**作用于当前实例加锁,进入同步代码前要获得当前实例的锁 **2. 静态方法:**作用于当前类加锁,进入同步代码前要获得当前类的锁 **3. 修饰代码块&…

偏向锁的原理与实战

文章目录 1. 偏向锁的核心原理2. 偏向锁代码演示3. 偏向锁的膨胀与撤销 1. 偏向锁的核心原理 如果不存在线程竞争的一个线程获得了锁,那么锁就进入偏向状态,此时Mark Word的结构变为偏向锁结构,锁对象的锁标志位(lock)…

Java并发 | 19.[锁机制] 偏向锁(CAS)

文章目录 1. 偏向锁分析回顾轻量级锁偏向锁的优势 2. 偏向锁(CAS)2.1. 偏向锁流程概述2.2. 锁升级 参考资料 1. 偏向锁分析 回顾轻量级锁 在上文 Java并发 | 18.[锁机制] 轻量级锁(CAS自旋锁)中对轻量级锁进行过解析&#xff0c…

Synchronized-偏向锁

偏向锁是什么? 是jdk1.6引入的一种锁优化方式。让 锁对象 偏心于第一次获取锁的线程,记住它的id,当下一次再有线程获取锁的时候,与记录的ID匹配,直接获取锁就行。是一种load-and-test的过程。 引入目的? …

面试题-- 什么是偏向锁

所谓的偏向,就是偏心,即锁会偏向于当前已经占有锁的线程 。 大部分情况是没有竞争的(某个同步块大多数情况都不会出现多线程同时竞争锁),所以可以通过偏向来提高性能。即在无竞争时,之前获得锁的线程再次获…

Java中的偏向锁,轻量级锁, 重量级锁解析

文章目录 参考文章Java 中的锁一些先修知识synchronized 关键字之锁的升级(偏向锁->轻量级锁->重量级锁)无锁 -> 偏向锁偏向锁的撤销(Revoke)偏向锁的批量再偏向(Bulk Rebias)机制偏向锁 -> 轻…

条件分布

1.离散型: 例1: 2.连续型:

关于多元正态分布的条件分布的证明

之前在机器学习 cs229学习笔记3 (EM alogrithm,Mixture of Gaussians revisited & Factor analysis )中直接给出了多元正态分布的条件概率 正好今天上课讲了多元正态分布的内容,但没有涉及条件概率,所以下来baidu了一下,找到一个不错的pp…