当前位置: 首页 > 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近期对模型进行大幅度内容审查,导致用户感到失望并开始流失。…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...