【多线程】synchronized原理

文章目录

  • 一、锁升级 (面试经常考)
    • 偏向锁
  • 二、锁消除
  • 三、锁粗化
    • 锁的粒度
  • 四、相关面试题


结合 锁策略,我们就可以总结出,synchronized具有以下特性:

  1. 乐观悲观,自适应
  2. 重量轻量,自适应
  3. 自旋挂起等待,自适应
  4. 非公平锁
  5. 可重入锁
  6. 不是读写锁

当代码执行到 synchronized 代码块中,JVM 大概要做哪些事情

一、锁升级 (面试经常考)

  • 刚开始 synchronized 加锁,首先锁会处于“偏向锁”状态
  • 遇到线程之间的锁竞争,升级到“轻量级锁”
  • 进一步的统计竞争出现的频次,达到一定程度之后,升级到“重量级锁”
    synchronized 加锁的时候,会经历:无锁 => 偏向锁 => 轻量级锁 => 重量级锁

轻量级锁和重量级锁在 各种锁策略这篇文章中有详细介绍

在这里我们理解一下什么是“偏向锁

偏向锁

偏向锁不是真的加锁,因为真的加锁开销比较大,偏向锁只是做个标记,标记的过程,非常的轻量高效(比轻量级锁还要轻量)

偏向锁不是真的"加锁",只是给对象头中做⼀个"偏向锁的标记",记录这个锁属于哪个线程

  • 如果后续没有其他线程来竞争该锁,那么就不⽤进⾏其他同步操作了(避免了加锁解锁的开销)
  • 如果后续有其他线程来竞争该锁(刚才已经在锁对象中记录了当前锁属于哪个线程了,很容易识别当前申请锁的线程是不是之前记录的线程),那就取消原来的偏向锁状态,就立即加锁,进⼊⼀般的轻量级锁状态
    偏向锁本质上相当于"延迟加锁",能不加锁就不加锁,尽量来避免不必要的加锁开销,但是该做的标记还是得做的,否则⽆法区分何时需要真正加锁

例子:
假设男主是⼀个锁,⼥主是⼀个线程。如果只有这⼀个线程来使⽤这个锁,那么男主⼥主即使不领证结婚(避免了⾼成本操作),也可以⼀直幸福的⽣活下去
但是⼥配出现了,也尝试竞争男主,此时不管领证结婚这个操作成本多⾼,⼥主也势必要把这个动作完成了,让⼥配死⼼

偏向锁 => 轻量级锁:出现竞争
轻量级锁 => 重量级锁:竞争激烈

上述锁升级的过程,主要也是为了能够让 synchronized 这个锁很好的适应不同的场景,就可以降低程序员的使用负担(程序员不用考虑太多,无脑使用 synchronized 就行了)

对于当前 JVM 的实现来说,上述锁升级的过程,属于“不可逆”(只能升级,不能降级),要想回到最初的状态,就需要再弄一个锁对象才可以

二、锁消除

编译器的优化策略


编译器会对你写的 synchronized 代码做出判定,判定这个地方是否确实需要加锁,如果这里没有必要加锁,就能够自动把 synchronized 给干掉(避免产生无意义的执行开销)

锁消除虽然存在,我们写代码的时候,也不能完全指望这个,无脑加锁

  • 锁消除只是一个辅助效果,给我们兜底,就别指望全给我们兜这个底
  • 毕竟编译器的判定有时候也没那么准确,尤其是在多线程环境下的代码

三、锁粗化

编译器的优化策略


锁的粒度

synchronized() {...
}
  • 里面的代码越多,“粒度越粗”
  • 代码越少,“粒度越细”
  • 得看代实际执行的代码,而不是有多少行,可能里面有方法调用,也算“代码量”

锁粗化就是把多个“细粒度”的锁,合并成“粗粒度”的锁

image.png|500

  • 一次加解锁过程,就把四次操作全部涵盖进去了

因为每次加锁都可能涉及到阻塞等待,如果拆成多次,那么总的阻塞时间就可能很长,为了缩短总的等待时间,提高执行效率,就可以使用“锁粗化”的操作

例子:汇报工作
领导给你汇报了三个活,让你今天搞定
领导下班的时候,你把这三个活都干完了,去向领导电话汇报

  1. 三个任务给领导分别打三个电话进行汇报
    • 锁的粒度太小了,每次给领导打电话,就相当与对领导加锁,这样都被嫌死了
    • 每次加一个小粒度的锁,频繁加锁,效率是非常低的
  2. 三个任务打一个电话一起汇报
    • 这样也会缩短整体的阻塞时间

四、相关面试题

image.png

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

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

相关文章

Gradio 快速开发网页应用

Gradio 是一个开源的 Python 框架,可以快速开发页面,Gradio 主要用于 AI 模型 Demo 的开发,通过几行代码可以快速生成一个 Web Demo,由于 AI 算法工程师使用的都是 Python 语言,使用 Python 开发 Demo 会相对简单&…

演示:基于WPF的DrawingVisual开发GS(2019)1822号矢量中国地图一

一、目的:基于WPF的DrawingVisual开发的矢量地图 二、预览 默认样式 深黑样式 深蓝色样式 深蓝色透明样式 演示:基于WPF的DrawingVisual开发GS(2019)1822号矢量中国地图二-CSDN博客VS2022,net7演示:基于WPF的DrawingVisual开发GS…

DVWA—SQL(Blind)实例

DVWA—SQL Injection(Blind)实例 预备知识 在SQL注入中会有回显注入和盲注入的形式,在前面的文章中展示了回显注入的情况,而盲注入就是当我输入查询语句的时候数据并不会直接显示在页面中而是以程序员规定的输出格式来进行显示&…

【数据结构和算法】(基础篇二)——链表

链表 数组最麻烦的地方就是其在建立之后大小固定,对于增删数据很不方便。链表的出现解决了这个问题,链表的元素不是在内存中连续存储的,而是通过指针链接在一起的节点集合,这样的设计让链表有了动态的大小。链表是树和图结构的基…

Windows11 WSL2 Ubuntu编译安装perf工具

在Windows 11上通过WSL2安装并编译perf工具(Linux性能分析工具)可以按以下步骤进行。perf工具通常与Linux内核一起发布,因此你需要确保你的内核版本和perf版本匹配。以下是安装和编译perf的步骤: 1. 更新并升级系统 首先&#x…

Unity数据持久化 之 Json序列化与反序列化

语法规则可以看这篇文章:Unity数据持久化 之 Json 语法速通-CSDN博客 Q:Unity是通过什么来对Json文件进行处理的? A:JsonUtility:Unity 提供了 JsonUtility 类,用于将对象序列化为 JSON 字符串或将 JSON 字符串反序列化为对象。…

大数据-72 Kafka 高级特性 稳定性-事务 (概念多枯燥) 定义、概览、组、协调器、流程、中止、失败

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…

DC-5靶机渗透测试

DC-5靶场 文章目录 DC-5靶场信息收集漏洞发现漏洞利用 --- 日志文件包含漏洞利用 --- 文件包含过滤器链的RCEshell反弹权限提升 信息收集 使用--scriptvuln扫描发现了一个thankyou.php界面 感觉会有问题,前往访问网站信息 漏洞发现 来到thankyou.php界面&#xff…

haproxy详解

目录 一、haproxy简介 二、什么是负载均衡 2.1 负载均衡的类型 2.2.1 硬件 2.2.2 四层负载均衡 2.2.3 七层负载均衡 2.2.4 四层和七层的区别 三、haproxy的安装及服务信息 3.1 示例的环境部署: 3.2 haproxy的基本配置信息 3.2.1 global 配置参数介绍 3…

sleuth+zipkin分布式链路追踪

概述 结构图 常见的链路追踪 cat zipkin pinpoint skywalking sleuth Sleuth介绍 Trace Span Annotation 使用Sleuth 添加依赖 <!--sleuth--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starte…

运维工具的衍化对运维工作的新挑战

运维工具的衍化对运维工作产生了深远的影响&#xff0c;这些影响体现在多个方面&#xff0c;包括提升运维效率、优化资源配置、增强故障应对能力、促进团队协作与沟通&#xff0c;以及面临新的挑战如数据安全和隐私保护等。运维工具的衍化对运维工作带来了多方面的新挑战&#…

Yolo-World初步使用

Yolo v8目前已经支持Yolo-World&#xff0c;整理一下初步使用步骤。 使用步骤 1 先下载Yolo-World的pt文件&#xff0c;下载地址&#xff1a;GitHub - AILab-CVC/YOLO-World: [CVPR 2024] Real-Time Open-Vocabulary Object Detection 官网应该是点这里&#xff08;有个笑脸…

【C#】读取与写入txt文件内容

在 C# 中读取和写入文本文件内容是一个常见的任务。以下是使用几种不同方法读取和写入文本文件的示例。 一、读取txt文件内容 1.1 使用 StreamReader using System; using System.IO;class Program {static void Main(){string filePath "C:\path\to\your\file.txt&qu…

QT多语言工具实现支持生成ts文件,ts文件和xlsx文件互转

一. 工具介绍 1.如果你是Qt项目,为多语言发愁的话,看到这篇文件,恭喜你有福啦!工具截图如下:​ 2.在项目开发的过程中,尽量将所有需要翻译的文本放在一个文件中,qml翻译用一个文件,cpp用一个,如下: test.h #pragma once /******************************************…

Java面试篇(线程池相关专题)

文章目录 1. 为什么要使用线程池2. 线程池的核心参数和线程池的执行原理2.1 线程池的核心参数2.2 线程池的执行原理 3. 线程池中常见的阻塞队列3.1 常见的阻塞队列3.2 ArrayBlockingQueue 和 LinkedBlockingQueue 的区别 4. 如何确定线程池的核心线程数4.1 应用程序中任务的类型…

【代码随想录】长度最小的子数组——滑动窗口

本博文为《代码随想录》的学习笔记。原文链接&#xff1a;代码随想录 题目 原题链接&#xff1a;长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, nums…

历史库,成本与性能如何兼得?| OceanBase应用实践

随着数据量的迅猛增长&#xff0c;企业和组织在数据库管理方面遭遇的挑战愈发凸显。数据库性能逐渐下滑、存储成本节节攀升&#xff0c;以及数据运维复杂性的增加&#xff0c;这些挑战使得DBA和开发者在数据管理上面临更大的压力。 为了应对这些挑战&#xff0c;对数据生命周期…

uni-app学习笔记

一、下载HBuilder https://www.dcloud.io/hbuilderx.html 上述网址下载对应版本&#xff0c;下载完成后进行解压&#xff0c;不需要安装&#xff0c;解压完成后&#xff0c;点击HBuilder X.exe文件进行运行程序 二、创建uni-app项目 此处我是按照文档创建的uni-ui项目模板…

DWG图纸识别工作

DWG图纸识别工作 目的&#xff1a;完成从DWG图纸中数据的提取&#xff0c;在数据提取之前先要对DWG图纸进行识别。得到某个图层的数据。 最终完成图纸建筑外轮廓线坐标数据的提取。 1、 DWG图纸&#xff0c;通过AutoCAD软件导出 DXF文件 2、 DXF文件上传到服务端&#xff0c;…

Java设计模式(适配器模式)

定义 将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作。 角色 目标抽象类&#xff08;Target&#xff09;&#xff1a;目标抽象类定义客户所需的接口&#xff08;在类适配器中&#xff0c;目标抽象类只能是接口&#xff09;。 适配器类…