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

article/2025/10/21 13:10:03

文章目录

  • 前言
  • 一、无锁
  • 二、偏向锁
  • 三、轻量级锁(自选锁)
  • 四、重量级锁
    • 锁升级场景


前言

JDK1.6为了减少获得锁和释放锁所带来的性能消耗,引入了“偏向锁”和“轻量级锁”,所以在JDK1.6里锁一共有四种状态,无锁状态,偏向锁状态,轻量级锁状态和重量级锁状态,它会随着竞争情况逐渐升级。锁可以升级但不能降级,意味着偏向锁升级成轻量级锁后不能降级成偏向锁。这种锁升级却不能降级的策略,目的是为了提高获得锁和释放锁的效率.

Java中的锁有几种状态:无锁 → 偏向锁 → 轻量级锁 → 重量级锁
在这里插入图片描述

一、无锁

偏向锁,顾名思义,它会偏向于第一个访问锁的线程

程序不会有锁的竞争。那么这种情况我们不需要加锁,所以这种情况下对象锁状态为无锁。

二、偏向锁

偏向锁,顾名思义,它会偏向于第一个访问锁的线程

  • 如果在运行过程中,同步锁只有一个线程访问,不存在多线程争用的情况,则线程是不需要触发同步的,这种情况下,就会给线程加一个偏向锁。线程第二次到达同步代码块时,会判断此时持有锁的线程是否就是自己,如果是则正常往下执行。由于之前没有释放锁,这里也就不需要重新加锁。如果自始至终使用锁的线程只有一个,很明显偏向锁几乎没有额外开销,性能极高。
  • 如果在运行过程中,遇到了其他线程抢占锁,则持有偏向锁的线程会被挂起,JVM会消除它身上的偏向锁,将锁恢复到标准的轻量级锁。偏向锁通过消除资源无竞争情况下的同步原语,进一步提高了程序的运行性能。一旦有第二个线程加入锁竞争,偏向锁就升级为轻量级锁(自旋锁)。升级为轻量级锁的时候需要撤销偏向锁,撤销偏向锁的时候会导致STW(stop the word)操作;

锁竞争:如果多个线程轮流获取一个锁,但是每次获取锁的时候都很顺利,没有发生阻塞,那么就不存在锁竞争。只有当某线程尝试获取锁的时候,发现该锁已经被占用,只能等待其释放,这才发生了锁竞争。

三、轻量级锁(自选锁)

自旋锁:自旋锁原理非常简单,如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态,它们只需要等一等(自旋),等持有锁的线程释放锁后即可立即获取锁,这样就避免用户线程和内核的切换的消耗。

  • 在轻量级锁状态下继续锁竞争,没有抢到锁的线程将自旋,即不停地循环判断锁是否能够被成功获取。长时间的自旋操作是非常消耗资源的,一个线程持有锁,其他线程就只能在原地空耗CPU,执行不了任何有效的任务,这种现象叫做忙等(busy-waiting)。如果锁竞争情况严重,某个达到最大自旋次数的线程,会将轻量级锁升级为重量级锁

四、重量级锁

  • 当后续线程尝试获取锁时,发现被占用的锁是重量级锁,则直接将自己挂起,等待将来被唤醒。在JDK1.6之前,synchronized直接加重量级锁,很明显现在得到了很好的优化。

重量级锁的特点:其他线程试图获取锁时,都会被阻塞,只有持有锁的线程释放锁之后才会唤醒这些线程。

优点缺点使用场景
偏向锁加锁和解锁不需要额外的消耗,和执行非同步方法比仅存在纳秒级的差距。如果线程间存在锁竞争,会带来额外的锁撤销的消耗。适用于只有一个线程访问同步块场景。
轻量级锁竞争的线程不会阻塞,提高了程序的响应速度。如果始终得不到锁竞争的线程使用自旋会消耗CPU。追求响应时间。同步块执行速度非常快。
重量级锁线程竞争不使用自旋,不会消耗CPU。线程阻塞,线程上下文切换耗费资源大,响应时间缓慢追求吞吐量。同步块执行速度较长。

锁升级场景

场景1: 经常只有某一个线程来加锁。

  • 加锁过程:也许获取锁的经常为同一个线程,这种情况下为了避免加锁造成的性能开销,加偏向锁
  • 偏向锁的执行流程如下:
    • 1、线程首先检查该对象头的线程ID是否为当前线程;
    • 2、A:如果对象头的线程ID和当前线程ID一直,则直接执行代码;B:如果不是当前线程ID则使用CAS方式替换对象头中的线程ID,如果使用CAS替换不成功则说明有线程正在执行,存在锁的竞争,这时需要撤销偏向锁,升级为轻量级锁。
    • 3、如果CAS替换成功,则把对象头的线程ID改为自己的线程ID,然后执行代码。
    • 4、执行代码完成之后释放锁,把对象头的线程ID修改为空。

场景2: 有线程来参与锁的竞争,但是获取锁的冲突时间很短。

  • 当开始有锁的竞争了,那么偏向锁就会升级到轻量级锁;
  • 线程获取锁出现冲突时,线程必须做出决定是继续在这里等,还是先去做其他事情,等会再来看看,而轻量级锁的采用了继续在这里等的方式。当发现有锁竞争,线程首先会使用自旋的方式循环在这里获取锁,因为使用自旋的方式非常消耗CPU。当一定时间内通过自旋的方式无法获取到锁的话,那么锁就开始升级为重量级锁了。

场景3: 有大量的线程参与锁的竞争,冲突性很高。

  • 当获取锁冲突多,时间越长的时候,线程肯定无法继续在这里死等了,所以只好先挂起,然后等前面获取锁的线程释放了锁之后,再开启下一轮的锁竞争,而这种形式就是我们的重量级锁。

————————————————
版权声明:本文为CSDN博主「carroll18」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_40722827/article/details/105598682


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

相关文章

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…

条件分布函数(离散-条件分布律)

一、离散随机变量的条件分布函数 1.0、条件分布函数定义 1.1、例 1.1.1、例1 1.1.2、例2 二、连续型随机变量的条件分布函数 2.1、连续随机变量的条件分布函数 2.2、条件概率密度函数

第三章 多维随机变量及其分布 3.3 条件分布

第三章 多维随机变量及其分布 3.3 条件分布 文章目录 第三章 多维随机变量及其分布 3.3 条件分布离散型随机变量的条件分布连续型随机变量的条件分布 离散型随机变量的条件分布 例: 求: 离散型的直接套条件概率的公式就行了。 连续型随机变量的条件分布…

~《概率论》~条件分布

《概率论》条件分布 文章目录 ~《概率论》~条件分布一、离散型随机向量的条件分布1.1、定义1.2、性质 二、连续型随机向量的条件分布2.1、定义2.2、性质 一、离散型随机向量的条件分布 1.1、定义 1.2、性质 二、连续型随机向量的条件分布 2.1、定义 2.2、性质

MCMC算法--Gibbs采样2:多元高斯分布的边际分布与条件分布推导

因为在下篇博客中会介绍Gibbs采样,代码示例用到的是多元高斯分布,所以对条件分布,边际分布公式必须写出来,所以博主整理了下。 参考文献为:http://fourier.eng.hmc.edu/e161/lectures/gaussianprocess/node7.html 由…