java多线程——synchronized的偏向锁、轻量级锁和重量级锁

在Java中,synchronized关键字是用于实现线程同步的一种机制,它提供了偏向锁、轻量级锁和重量级锁三种锁状态来优化同步性能。以下是这三种锁的原理和使用方法的详细解释:

一、偏向锁(Biased Locking)

  1. 原理

    • 偏向锁的目的是为了优化只有一个线程访问同步块的场景。在大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得。偏向锁会在对象头(Mark Word)中存储锁偏向的线程ID,以后该线程进入和退出同步块时只需要检查是否为偏向锁、锁标志位以及ThreadID即可。
    • 偏向锁的线程会检查锁对象的Mark Word中是否存放着自己的线程ID。如果存放的是当前线程的ID,表示偏向锁现在就是偏向当前线程的,无需再尝试获得锁,可以直接进入同步块。如果不是当前线程的ID,则会发生竞争,当前线程会尝试通过CAS(Compare-And-Swap)操作更新锁对象Mark Word中的线程ID。
    • 如果更新成功,锁重新偏向为当前线程,锁仍然为偏向锁。如果更新失败,表示之前的线程还在持有锁,那么当前线程会进行CAS自旋操作,当达到一定次数后还没成功,则会发生偏向锁到轻量级锁的升级。
  2. 使用方法

    • 偏向锁是Java虚拟机(JVM)在JDK 1.6及以后版本中默认启用的优化机制,无需开发者显式使用。但可以通过JVM参数-XX:+UseBiasedLocking来显式启用或-XX:-UseBiasedLocking来禁用偏向锁。
    • 偏向锁在应用程序启动几秒钟(默认延迟4秒)之后才会激活,可以使用-XX:BiasedLockingStartupDelay=0参数关闭延迟,让其在程序启动时立刻启动。

二、轻量级锁

  1. 原理

    • 轻量级锁是为了减少线程从内核态和用户态的切换而设计的,适用于多线程竞争不激烈的情况。它通过CAS机制来竞争锁,避免了重量级锁产生的性能消耗。
    • 当一个线程尝试获取轻量级锁时,JVM会首先在抢锁线程的栈帧中建立一个锁记录(Lock Record),用于存储对象目前的Mark Word拷贝。然后,抢锁线程通过自旋操作尝试将内置锁对象头的Mark Word的锁记录指针(ptr_lock_record)更新为抢锁线程中锁记录的地址。如果更新成功,这个线程就拥有了这个对象锁。
    • 轻量级锁主要有两种:普通自旋锁和自适应自旋锁。普通自旋锁就是当线程来竞争锁时,抢锁线程会原地等待,直到那个占有锁的线程释放锁。自适应自旋锁则会根据线程之前获取锁的成功率来动态调整自旋次数。
  2. 使用方法

    • 轻量级锁也是JVM默认启用的优化机制,无需开发者显式使用。
    • 开发者可以通过JVM参数来调整自旋次数,例如-XX:PreBlockSpin来设置普通自旋锁的自旋次数。

三、重量级锁

  1. 原理

    • 重量级锁通过JVM中的监视器(Monitor)来实现,它保证了任何时间内只允许一个线程通过监视器保护的临界区代码。
    • 当一个线程尝试获取重量级锁时,如果该锁已被其他线程持有,则当前线程会被阻塞,并放入竞争队列(Cxq)中等待。当持有锁的线程释放锁时,JVM会从竞争队列中唤醒一个线程来竞争锁。竞争成功的线程会成为新的持有者,并继续执行临界区代码。
    • 重量级锁会导致线程在用户态和核心态之间切换,带来较大的性能损耗。因此,在多线程竞争激烈的情况下,应尽量避免使用重量级锁。
  2. 使用方法

    • 重量级锁是synchronized关键字在竞争激烈情况下的默认行为,无需开发者显式使用。
    • 开发者可以通过优化代码逻辑、减少同步块的范围或使用其他并发工具(如ReentrantLock、Semaphore等)来避免重量级锁的使用。

四、代码举例 

一、偏向锁代码示例

偏向锁是JVM在JDK 1.6及以后版本中默认启用的优化机制,无需开发者显式使用。但可以通过JVM参数来启用或禁用偏向锁,并观察其状态变化。

public class BiasedLockingDemo {private static final Object lock = new Object();public static void main(String[] args) throws InterruptedException {// 禁用偏向锁延迟,使偏向锁立即生效System.setProperty("java.vm.ci.compilerThreshold", "0");// 通过JVM参数设置立即生效偏向锁// -XX:BiasedLockingStartupDelay=0 需要在启动JVM时设置// 打印锁对象的初始状态printLockState(lock);// 持有偏向锁synchronized (lock) {// 打印锁对象在持有偏向锁时的状态printLockState(lock);}// 打印锁对象在释放偏向锁后的状态printLockState(lock);}// 使用jol工具打印锁对象的状态// 需要添加jol依赖,并在代码中引入相关类// <dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.16</version></dependency>private static void printLockState(Object obj) {// 使用jol的ClassLayout.parseInstance方法打印对象内部状态// 这里省略了具体的jol代码实现,需要自行添加// System.out.println(ClassLayout.parseInstance(obj).toPrintable());}
}

注意:上述代码中的printLockState方法需要使用JOL(Java Object Layout)工具来实现,该工具可以打印出Java对象的内部布局和状态。由于JOL工具的使用涉及较多细节,这里省略了具体的代码实现,需要开发者自行添加。

另外,偏向锁的状态变化可以通过观察锁对象的Mark Word来确认。在JVM中,Mark Word存储了对象的哈希码、分代年龄、锁标记位等信息。当偏向锁被启用时,Mark Word中会存储偏向线程的ID。

二、轻量级锁代码示例

轻量级锁也是JVM默认启用的优化机制,无需开发者显式使用。但可以通过观察多线程竞争锁的行为来间接了解轻量级锁的工作原理。

public class LightweightLockingDemo {private static final Object lock = new Object();public static void main(String[] args) {Thread t1 = new Thread(() -> {synchronized (lock) {// 模拟同步块中的操作try {Thread.sleep(100); // 让出CPU时间片,模拟其他线程竞争锁} catch (InterruptedException e) {Thread.currentThread().interrupt();}System.out.println("Thread 1 holds the lock");}});Thread t2 = new Thread(() -> {synchronized (lock) {System.out.println("Thread 2 holds the lock");}});t1.start();t2.start();}
}

在这个示例中,两个线程t1t2竞争同一个锁对象lock。由于轻量级锁的存在,当t1持有锁时,t2会尝试通过CAS操作来获取锁。如果t1很快释放锁,t2可能会成功获取锁并打印出“Thread 2 holds the lock”。如果t1持有锁时间较长,t2可能会进入自旋等待状态,直到t1释放锁。

三、重量级锁代码示例

重量级锁是多线程竞争激烈时的默认行为,也无需开发者显式使用。但可以通过构造一个多线程竞争锁的场景来观察重量级锁的行为。

public class HeavyweightLockingDemo {private static final Object lock = new Object();public static void main(String[] args) {Runnable task = () -> {synchronized (lock) {// 模拟同步块中的长时间操作try {Thread.sleep(1000); // 让线程持有锁一段时间} catch (InterruptedException e) {Thread.currentThread().interrupt();}System.out.println(Thread.currentThread().getName() + " holds the lock");}};// 启动多个线程来竞争锁for (int i = 0; i < 10; i++) {new Thread(task, "Thread-" + i).start();}}
}

在这个示例中,启动了10个线程来竞争同一个锁对象lock。由于线程数量较多,且每个线程都会持有锁一段时间(通过Thread.sleep模拟),因此会导致多线程竞争激烈。在这种情况下,JVM可能会将轻量级锁升级为重量级锁,以保证线程同步的正确性。

注意:上述代码示例中的锁升级行为是JVM内部实现的,开发者无法直接观察到锁的具体升级过程。但可以通过观察程序的运行情况和性能表现来间接了解锁升级的影响。例如,当多线程竞争激烈时,程序的响应时间可能会变长,CPU使用率可能会升高,这些都是重量级锁带来的性能损耗的表现。 

五、总结

  • 偏向锁:适用于只有一个线程访问同步块的场景,通过存储锁偏向的线程ID来优化性能。在锁对象的对象头中记录一下当前获取到该锁的线程ID,该线程下次如果又来获取该锁就可以直接获取到了
  • 轻量级锁:适用于多线程竞争不激烈的情况,通过CAS机制和自旋操作来竞争锁。由偏向锁升级而来,当一个线程获取到锁后,此时这把锁是偏向锁,此时如果有第二个线程来竞争锁,偏向锁就会升级为轻量级锁,之所以叫轻量级锁,是为了和重量级锁区分开来,轻量级锁底层是通过自旋来实现的,并不会阻塞线程
  • 重量级锁:适用于多线程竞争激烈的情况,通过监视器来保证线程同步,但会导致较大的性能损耗。如果次数过多仍然没有获取到锁,则会升级为重量级锁,重量级锁会导致线程阻塞

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/887377.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Otter 安装流程

优质博文&#xff1a;IT-BLOG-CN 一、背景 随着公司的发展&#xff0c;订单库的数据目前已达到千万级别&#xff0c;需要进行分表分库&#xff0c;就需要对数据进行迁移&#xff0c;我们使用了otter&#xff0c;这里简单整理下&#xff0c;otter 的安装过程&#xff0c;希望对…

如何解决Jupyter command `jupyter-contrib` not found.

目录 (base) C:\Users\hello>pip show jupyter_contrib_nbextensions Name: jupyter-contrib-nbextensions Version: 0.7.0 Summary: A collection of Jupyter nbextensions. Home-page: https://github.com/ipython-contrib/jupyter_contrib_nbextensions.git Author: ipyt…

Gitee markdown 使用方法(持续更新)

IPKISS 获取仿真器件的名称 引言正文标题换行第一种------在行末尾手动键入两个空格第二种------额外换行一次&#xff0c;即两行中间留一个空行 缩进与反缩进代码块行内代码添加图片添加超链接 加粗&#xff0c;倾斜&#xff0c;加粗倾斜 引言 有些保密性的文件或者教程&…

Adobe Illustrator 2024 安装教程与下载分享

介绍一下 下载直接看文章末尾 Adobe Illustrator 是一款由Adobe Systems开发的矢量图形编辑软件。它广泛应用于创建和编辑矢量图形、插图、徽标、图标、排版和广告等领域。以下是Adobe Illustrator的一些主要特点和功能&#xff1a; 矢量绘图&#xff1a;Illustrator使用矢量…

golang学习5

为结构体添加方法 异常处理过程

分布式光伏与储能协调控制策略的应用分析

安科瑞汪洋/汪小姐/汪女士---Acrelwy 摘 要&#xff1a;针对光伏发电的随机性、波动性、间歇性特征,研发了分布式光伏与储能协调控制策略,并在镇江地调开展分布式电源光储协控试点应用&#xff0c;开展光储协调控制策略研究&#xff0c;实时采集分布式光伏电站、储能电站、试点…

sd webui整合包怎么安装comfyui

环境: sd webui整合包 comfyui 问题描述: sd webui整合包怎么安装comfyui 扩展安装不成功 解决方案: 1.直接下载 ,解压到SD文件夹里(或者git拉一下) 2.ComfyUI模型共享:如果本机部署过Webui,那么ComfyUI可以与WebUI公用一套模型,防止复制大量模型浪费空间 将…

Utf8Json 枚举序列化为整型(默认string)

Utf8Json 枚举序列化为整型 找到 StandardResolver.cs, 更换EnumResolver. Default 为EnumResolver. UnderlyingValue

网络基础 - 地址篇

一、IP 地址 IP 协议有两个版本&#xff0c;IPv4 和 IPv6IP 地址(IPv4 地址)是一个 4 字节&#xff0c;32 位的正整数&#xff0c;通常使用 “点分十进制” 的字符串进行表示&#xff0c;例如 192.168.0.1&#xff0c;用点分割的每一个数字表示一个字节&#xff0c;范围是 0 ~…

Vue3+SpringBoot3+Sa-Token+Redis+mysql8通用权限系统

sa-token支持分布式token 前后端代码&#xff0c;地球号: bright12389

Leetcode 336 回文对

示例 1&#xff1a; 输入&#xff1a;words ["abcd","dcba","lls","s","sssll"] 输出&#xff1a;[[0,1],[1,0],[3,2],[2,4]] 解释&#xff1a;可拼接成的回文串为 ["dcbaabcd","abcddcba","sl…

基于Vue+SpringBoot的考研学习分享平台设计与实现

摘要 考研学习分享平台是一个专注于为考研学子提供全面学习资源和经验分享的互动社区。这里汇聚了众多考研成功者的经验心得&#xff0c;涵盖各个学科领域的备考技巧和策略。平台不仅提供丰富的学习资料&#xff0c;还设有在线答疑、模拟考试等实用功能&#xff0c;帮助考生高…

【C++】C++11新特性详解:可变参数模板与emplace系列的应用

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶String使用String模拟实现Vector使用及其模拟实现List使用及其模拟实现容器适配器Stack与QueuePriori…

TCP为什么需要三次握手?两次握手或四次握手可以吗?

&#xff08;1&#xff09;三次握手可以保证双方具有接收和发送的能力 第一次握手服务端可以确认客户端的发送能力和服务端的接收能力是正常的&#xff1b;第二次握手客户端可以确认客户端和服务端的收发能力是正常的&#xff0c;但是服务端无法确认客户端的接收能力是正常的&…

nature communications论文 解读

题目《Transfer learning with graph neural networks for improved molecular property prediction in the multi-fidelity setting》 这篇文章主要讨论了如何在多保真数据环境&#xff08;multi-fidelity setting&#xff09;下&#xff0c;利用图神经网络&#xff08;GNNs&…

Cmakelist.txt之Linux-redis配置

1.cmakelist.txt cmake_minimum_required(VERSION 3.16) ​ project(redis_linux_test LANGUAGES C) ​ ​ ​ add_executable(redis_linux_test main.c) ​ # 设置hiredis库的头文件路径和库文件路径 set(Hiredis_INCLUDE_DIR /usr/local/include/hiredis) set(Hiredis_LIBRA…

基于Qt/C++/Opencv实现的一个视频中二维码解析软件

本文详细讲解了如何利用 Qt 和 OpenCV 实现一个可从视频和图片中检测二维码的软件。代码实现了视频解码、多线程处理和界面更新等功能&#xff0c;是一个典型的跨线程图像处理项目。以下分模块对代码进行解析。 一、项目的整体结构 项目分为以下几部分&#xff1a; 主窗口 (M…

C语言练习.if.else语句.strstr

今天在做题之前&#xff0c;先介绍一下&#xff0c;新学到的库函数strstr 想要使用它&#xff0c;要先给它一个头文件<string.h> char *strstr(const char*str1,const char*str2); 首先&#xff1a;1.strstr的返回值是char&#xff0c;字符类型的。 2.两个实参&#xff…

丹摩|丹摩智算平台深度评测

1. 丹摩智算平台介绍 随着人工智能和大数据技术的快速发展&#xff0c;越来越多的智能计算平台涌现&#xff0c;为科研工作者和开发者提供高性能计算资源。丹摩智算平台作为其中的一员&#xff0c;定位于智能计算服务的提供者&#xff0c;支持从数据处理到模型训练的全流程操作…

美创科技入选2024数字政府解决方案提供商TOP100!

11月19日&#xff0c;国内专业咨询机构DBC德本咨询发布“2024数字政府解决方案提供商TOP100”榜单。美创科技凭借在政府数据安全领域多年的项目经验、技术优势与创新能力&#xff0c;入选收录。 作为专业数据安全产品与服务提供商&#xff0c;美创科技一直致力于为政府、金融、…