当前位置: 首页 > news >正文

高薪程序员必修课-Java中 Synchronized锁的升级过程

目录

前言

锁的升级过程

1. 偏向锁(Biased Locking)

原理:

示例:

2. 轻量级锁(Lightweight Locking)

原理:

示例:

3. 重量级锁(Heavyweight Locking)

原理:

示例:

注意事项

总结


前言

        在Java中,synchronized 关键字用于实现线程同步,确保在同一时间只有一个线程可以访问被保护的代码块。为了提高性能,Java对锁的实现进行了优化,采用了锁的升级机制。锁的升级过程包括从偏向锁、轻量级锁到重量级锁的升级。下面详细讲解锁的升级过程,并提供相应的示例。

锁的升级过程

  1. 偏向锁(Biased Locking)
  2. 轻量级锁(Lightweight Locking)
  3. 重量级锁(Heavyweight Locking)

1. 偏向锁(Biased Locking)

原理:

        偏向锁是为了优化只有一个线程访问同步块的情况。默认情况下,对象头中的标记字段(Mark Word)存储了偏向锁的线程ID。只有当另一个线程尝试获取锁时,偏向锁才会升级为轻量级锁。

示例:
public class BiasedLockingExample {private static final Object lock = new Object();public static void main(String[] args) {synchronized (lock) {// 第一个线程获得偏向锁System.out.println("Thread 1 has acquired the biased lock.");}}
}

在这个示例中,synchronized 关键字使得 lock 对象在第一次被线程获取时进入偏向锁状态。

2. 轻量级锁(Lightweight Locking)

原理:

        当另一个线程尝试获取已偏向的锁时,偏向锁升级为轻量级锁。轻量级锁使用CAS(Compare-And-Swap)操作来避免阻塞。当竞争不激烈时,轻量级锁的性能优于重量级锁。

示例:
public class LightweightLockingExample {private static final Object lock = new Object();public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {synchronized (lock) {// 第一个线程获得偏向锁System.out.println("Thread 1 has acquired the lock.");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});Thread t2 = new Thread(() -> {synchronized (lock) {// 第二个线程尝试获取锁,偏向锁升级为轻量级锁System.out.println("Thread 2 has acquired the lock.");}});t1.start();Thread.sleep(100); // 确保t1先获得锁t2.start();t1.join();t2.join();}
}

在这个示例中,第二个线程尝试获取已经被第一个线程偏向的锁,导致偏向锁升级为轻量级锁。

3. 重量级锁(Heavyweight Locking)

原理:

        当多个线程频繁竞争同一个锁时,轻量级锁会不断地进行CAS操作,这时轻量级锁会升级为重量级锁(互斥锁)。重量级锁会使用操作系统的同步机制,使得其他线程在获取锁时进入阻塞状态,减少CPU的自旋消耗。

示例:
public class HeavyweightLockingExample {private static final Object lock = new Object();public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {synchronized (lock) {// 第一个线程获得锁System.out.println("Thread 1 has acquired the lock.");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}}});Thread t2 = new Thread(() -> {synchronized (lock) {// 第二个线程尝试获取锁,锁升级为重量级锁System.out.println("Thread 2 has acquired the lock.");}});Thread t3 = new Thread(() -> {synchronized (lock) {// 第三个线程尝试获取锁,锁已是重量级锁System.out.println("Thread 3 has acquired the lock.");}});t1.start();Thread.sleep(100); // 确保t1先获得锁t2.start();Thread.sleep(100); // 确保t2在t1之后尝试获取锁t3.start();t1.join();t2.join();t3.join();}
}

在这个示例中,第三个线程尝试获取已经被第二个线程竞争的轻量级锁,导致轻量级锁升级为重量级锁。

注意事项

  1. 适用场景

    • 偏向锁适用于只有一个线程访问同步块的场景。
    • 轻量级锁适用于多个线程交替访问同步块且竞争不激烈的场景。
    • 重量级锁适用于多个线程频繁竞争同一个锁的场景。
  2. 锁升级不可逆

    • 一旦锁从偏向锁升级为轻量级锁或重量级锁,无法降级为偏向锁。为了性能优化,尽量避免频繁的锁竞争。
  3. 启用和禁用偏向锁

    • 默认情况下,偏向锁是启用的。如果需要禁用,可以在JVM启动参数中添加 -XX:-UseBiasedLocking

总结

        Java中 synchronized 锁的升级过程包括从偏向锁、轻量级锁到重量级锁:

  1. 偏向锁:优化单线程访问的场景,减少不必要的同步开销。
  2. 轻量级锁:通过CAS操作进行自旋,适用于竞争不激烈的场景。
  3. 重量级锁:使用操作系统同步机制进行阻塞,适用于高竞争的场景。

通过了解锁的升级过程,可以更好地优化并发程序的性能,避免不必要的锁竞争和性能开销。

相关文章:

高薪程序员必修课-Java中 Synchronized锁的升级过程

目录 前言 锁的升级过程 1. 偏向锁(Biased Locking) 原理: 示例: 2. 轻量级锁(Lightweight Locking) 原理: 示例: 3. 重量级锁(Heavyweight Locking)…...

Vue项目打包上线

Nginx 是一个高性能的开源HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。它在设计上旨在处理高并发的请求,是一个轻量级、高效能的Web服务器和反向代理服务器,广泛用于提供静态资源、负载均衡、反向代理等功能。 1、下载nginx 2、…...

算法题中常用的C++功能

文章目录 集合优先队列双端队列排序时自定义比较函数最大数值字符串追加:删除:子串: 元组vector查找创建和初始化赋值: 字典map引入头文件定义和初始化插入元素访问元素更新元素删除元素检查元素存在遍历元素int和string转换 集合…...

左扰动和右扰动

在SLAM(Simultaneous Localization and Mapping)中,使用左扰动还是右扰动主要取决于你如何定义坐标系和你希望扰动影响的姿态表示。这通常与你的坐标系选择和你正在解决的具体问题有关。 左扰动通常用于以下情况: 当你使用局部坐…...

【计算机网络】期末复习(2)

目录 第一章:概述 第二章:物理层 第三章:数据链路层 第四章:网络层 第五章:传输层 第一章:概述 三大类网络 (1)电信网络 (2)有线电视网络 &#xff0…...

ojdbc8-full Oracle JDBC 驱动程序的一个完整发行版各文件的功能

文章目录 1. ojdbc8.jar2. ons.jar -3. oraclepki.jar -4. orai18n.jar -5. osdt_cert.jar -6. osdt_core.jar -7. ojdbc.policy -8. README.txt -9. simplefan.jar -10. ucp.jar -11. xdb.jar - ojdbc8-full 是 Oracle JDBC 驱动程序的一个完整发行版,包含了连接和…...

在Linux环境下使用sqlite3时,如果尝试对一个空表进行操作(例如插入数据),可能会遇到表被锁定的问题。

在Linux环境下使用sqlite3时,如果尝试对一个空表进行操作(例如插入数据),可能会遇到表被锁定的问题。这通常是因为sqlite3在默认情况下会对空表进行“延迟创建”,即在实际需要写入数据之前,表不会被真正创建…...

【目标检测】DINO

一、引言 论文: DINO: DETR with Improved DeNoising Anchor Boxes for End-to-End Object Detection 作者: IDEA 代码: DINO 注意: 该算法是在Deformable DETR、DAB-DETR、DN-DETR基础上的改进,在学习该算法前&#…...

一文包学会ElasticSearch的大部分应用场合

ElasticSearch 官网下载地址:Download Elasticsearch | Elastic 历史版本下载地址1:Index of elasticsearch-local/7.6.1 历史版本下载地址2:Past Releases of Elastic Stack Software | Elastic ElasticSearch的安装(windows) 安装前所…...

创建kobject

1、kobject介绍 kobject的全称是kernel object,即内核对象。每一个kobject都会对应系统/sys/下的一个目录。 2、相关结构体和api介绍 2.1 struct kobject // include/linux/kobject.h 2.2 kobject_create_and_add kobject_create_and_addkobject_createkobj…...

数据结构 - C/C++ - 树

公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 树的概念 结构特性 树的样式 树的存储 树的遍历 节点增删 二叉搜索树 平衡二叉树 树的概念 二叉树是树形结构,是一种非线性结构。 非线性结构:在二叉树中&#x…...

Linux源码阅读笔记12-RCU案例分析

在之前的文章中我们已经了解了RCU机制的原理和Linux的内核源码,这里我们要根据RCU机制写一个demo来展示他应该如何使用。 RCU机制的原理 RCU(全称为Read-Copy-Update),它记录所有指向共享数据的指针的使用者,当要修改构想数据时&…...

【C++】双线性差值算法实现RGB图像缩放

双线性差值算法 双线性插值(Bilinear Interpolation)并不是“双线性差值”,它是一种在二维平面上估计未知数据点的方法,通常用于图像处理中的图像缩放。 双线性插值的基本思想是:对于一个未知的数据点,我…...

计算机网络知识普及之四元组

在涉及到TCP/UDP等IP类通信协议时,存在四元组概念 这里只是普及使用 先来一些前置知识,什么是IP协议? IP协议全称为互联网协议,处于网络层中,主要作用是标识网络中的设备,每个设备的IP地址是唯一的。 在网…...

深度探讨网络安全:挑战、防御策略与实战案例

目录 ​编辑 一、引言 二、网络安全的主要挑战 恶意软件与病毒 数据泄露 分布式拒绝服务攻击(DDoS) 内部威胁 三、防御策略与实战案例 恶意软件防护 网络钓鱼防护 数据泄露防护 总结 一、引言 随着信息技术的迅猛发展,网络安全问…...

“穿越时空的机械奇观:记里鼓车的历史与科技探秘“

在人类文明的发展历程中,科技的创新与进步不仅仅推动了社会的进步,也为我们留下了丰富的文化遗产。记里鼓车,作为一种古老的里程计量工具,其历史地位和技术成就在科技史上具有重要的意义。本文将详细介绍记里鼓车的起源、结构原理…...

DevOps CMDB平台整合Jira工单

背景 在DevOps CMDB平台建设的过程中,我们可以很容易的将业务应用所涉及的云资源(WAF、K8S、虚拟机等)、CICD工具链(Jenkins、ArgoCD)、监控、日志等一次性的维护到CMDB平台,但随着时间的推移,…...

Vue-路由

路由简介 SPA单页面应用。导航区和展示区 单页Web应用整个应用只有一个完整的页面点击页面中的导航连接不会刷新页面,只会做页面的局部更新数据需要通过ajax请求获取 路由:路由就是一组映射关系,服务器接收到请求时,根据请求路…...

【Rust入门教程】安装Rust

文章目录 前言Rust简介Rust的安装更新与卸载rust更新卸载 总结 前言 在当今的编程世界中,Rust语言以其独特的安全性和高效性吸引了大量开发者的关注。Rust是一种系统编程语言,专注于速度、内存安全和并行性。它具有现代化的特性,同时提供了低…...

Character.ai因内容审查流失大量用户、马斯克:Grok-3用了10万块英伟达H100芯片

ChatGPT狂飙160天,世界已经不是之前的样子。 更多资源欢迎关注 1、爆火AI惨遭阉割,1600万美国年轻人失恋?Character.ai被爆资金断裂 美国流行的社交软件Character.ai近期对模型进行大幅度内容审查,导致用户感到失望并开始流失。…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

CppCon 2015 学习:Time Programming Fundamentals

Civil Time 公历时间 特点&#xff1a; 共 6 个字段&#xff1a; Year&#xff08;年&#xff09;Month&#xff08;月&#xff09;Day&#xff08;日&#xff09;Hour&#xff08;小时&#xff09;Minute&#xff08;分钟&#xff09;Second&#xff08;秒&#xff09; 表示…...

qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001

qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类&#xff0c;直接把源文件拖进VS的项目里&#xff0c;然后VS卡住十秒&#xff0c;然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分&#xff0c;导致编译的时候找不到了。因…...