【多线程】synchronized 原理

news2024/7/6 18:51:36

1. 写在前面

本章节主要介绍 synchronized 的一些内部优化机制,这些机制存在的目的呢就是让 synchronized 这把锁更高效更好用!


2. 锁升级/锁膨胀

JVM 将 synchronized 锁分为以下四种状态:

无锁,偏向锁,轻量级锁,重量级锁

在 synchronized 进行加锁的时候,首先会进入到偏向锁的状态,偏向锁不是真正的加锁,而是占个位置,有需要再加锁,没有需要就不加锁,这样一来则减少了加锁解锁的开销,一旦在使用过程中,另一个线程也尝试加锁,那么在另一个线程加锁前,持有偏向锁状态的线程会迅速的把偏向锁升级为真正的加锁状态。

如果在使用过程中,没有其他线程尝试加锁,也就是没有出现锁竞争,那么在 synchronized 执行完后,取消偏向锁即可。

当 synchronized 发生锁竞争时,就会从偏向锁升级成轻量级锁,此时 synchronized 相当于是通过自旋的方式来进行加锁的。

升级成轻量级锁后,如果其他线程很快的释放锁,自旋的方式是很划算的,如果迟迟拿不到锁,一直自旋占用 CPU 资源其实并不划算,而 synchronized 并不是无休止的自旋,自旋到一定程度,发现还是获取不到锁,就会再次升级成重量级锁(挂起等待锁)。

在 synchronized 内部的自旋循环中,有一个计数器,记录循环了多少次,循环多久了,达到一定程度就会执行重量级锁的逻辑,如果线程进行了重量级加锁,并且发生了锁竞争,此时未获取到锁的线程就会被放入阻塞队列中,暂时不参与 CPU 调度了,直到锁释放,才有机会被调度到,才有机会获取到锁。

注意:在 JVM 主流实现中,没有锁降级,当前锁只能升级,只要指定的锁对象,已经被升级了,就回不了头了!


3. 锁消除

锁消除是由编译器智能判定的,看当前的代码是否有必要加锁,如果当前的场景不需要加锁,程序猿加了也是白加,编译器就会自动把锁给消除掉。

比如 StringBuffer 很多关键方法都带有 synchronized,但是如果在单线程中使用 StringBuffer,此时加锁与不加锁完全没有任何区别,而且加锁还有更多的开销,于是编译器就会把这些加锁操作给自动取消了,这就是锁消除机制。


4. 锁粗化

这里就涉及到一个术语,锁的粒度。

锁的粒度:synchronized 包含的代码越多,粒度就越粗,包含的代码越少,粒度就越细。

举个例子:


public void test() {
    synchronized (this) {
        // 10w 行代码...
        // ...
    }
}

这里的写法就相当夸张了,开发中基本不存在,但这样显而易见一个 synchronized 包裹的代码块中有 10w 行代码,这里的粒度是非常粗的,我们要尽量避免这种情况,在通常情况下,锁的粒度越小是越好的。

因为加锁部分的代码是不能并发执行的,粒度越细,能并发的代码就越多了。

但是在有些情况下,锁的粒度真的越细越好吗?其实也不一定,比如:


public void test() {
    synchronized (this) {
        // 10 行代码...
    }
    // 2 行代码...
    synchronized (this) {
        // 10 行代码...
    }
    // 2 行代码...
    synchronized (this) {
        // 10 行代码...
    }
}

此时两次相邻加锁之间,间隙非常少,此时还不如用一个 synchronized 包裹起来!

为什么,因为加锁解锁也是有开销的!

这里试想一下,有一天领导给你安排了三个任务,领导要求你做完后打电话进行汇报。

做法1:

每当完成一个任务就打电话给领导汇报一次:

第一次打电话:领导,我任务一完成了

第二次打电话:领导,我任务二完成了

第三次打电话:对不起,您拨打的电话正在通话中,请稍后再拨...

最后领导不耐烦,你被炒鱿鱼了。

做法2:

把三个任务都完成了,一次性跟领导汇:

打电话:领导,我任务一,二,三都完成了!领导:小伙子不错啊!

最后领导满意,你升职加薪。

所以我们要结合代码来适当的调整锁的粒度


5. 常见锁策略相关面试题

5.1 你是如何理解乐观锁和悲观锁的?

乐观锁认为多个线程访问同一个变量冲突的概率不大,所以乐观锁也不会真正的加搜,会直接尝试访问数据,在访问的同时去识别当前数据是否出现访问冲突,也就是引入一个版本号,借助版本号来识别当前的数据访问是否冲突了

悲观锁的实现就是先加锁,他认为多个线程访问同一个变量的冲突率很大,每次都会真正的加锁,比如借助操作系统提供的mutex,只有获取到了锁,才会操作数据,获取不到锁就会阻塞等待

5.2 介绍下读写锁

读写锁就是把读操作和写操作分别进行加锁

  • 读锁和读锁之间不存在互斥

  • 写锁和写锁之间存在互斥

  • 写锁和读锁之间存在互斥

读写锁最主要用在"频繁读,不频繁写"的场景中

5.3 什么是自旋锁,为什么要使用自旋锁策略呢?缺点是什么?

自旋锁如果获取锁失败,就会立即尝试获取锁,无限循环,获取到锁位置,这样的好处是,一旦锁被释放,就能在第一时间发现,也就是能第一时间获取锁,但如果其他线程锁持有的时间太长,就会浪费CPU资源,所以自旋锁更适合在锁持有时间短的场景下使用

5.4 synchronized 是可重入锁吗?

是可重入锁,可重入锁指的是一个线程对同一个对象连续加锁两次,如果没有出现死锁,就是不可重入锁

具体实现是在锁中记录该锁持有的线程身份,以及一个计数器(记录加锁次数),如果发现当前加锁的线程是持有锁的线程,则直接计数自增。


下期预告:【多线程】JUC的常见类

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

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

相关文章

ENSP软件的基本使用命令(第三十一课)

ENSP软件的基本使用命令(第三十一课) 下面的图片是今天操作的核心基础操作 1 命令行页面 交换机 路由器 PC机 分别展示一下 页面的样子 2 基本命令结构

K8S系列文章 之 容器存储基础 Volume

Volume Volume是容器数据卷。我们经常创建删除一些容器,但有时候需要保留容器中的一些数据,这时候就用到了Volume。它也是容器之间数据共享的技术,可以将容器中产生的数据同步到本地。实际就是把容器中的目录挂载到运行着容器的服务器或个人…

Last-Mile Embodied Visual Navigation 论文阅读

论文阅读 题目:Last-Mile Embodied Visual Navigation 作者:JustinWasserman, Karmesh Yadav 来源:CoRL 时间:2023 代码地址:https://jbwasse2.github.io/portfolio/SLING Abstract 现实的长期任务(例如…

Spring Cloud Gateway过滤器GlobalFilter详解

一、过滤器的场景 在springCloud架构中,网关是必不可少的组件,它用于服务路由的转发。对客户端进行屏蔽微服务的具体细节,客户端只需要和网关进行交互。所以网关顾名思义,就是网络的一个关卡。它就是一座城的城门守卫。所以这个守…

10亿数据、查询<10s,论基于OLAP搭建广告系统的正确姿势

更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 由于流量红利逐渐消退,越来越多的广告企业和从业者开始探索精细化营销的新路径,取代以往的全流量、粗放式的广告轰炸。精细化营销意味着要在…

抓包神器-burp

Burp Suite是一款信息安全从业人员必备的集成型的渗透测试工具,它采用自动测试和半自动测试的方式,包含了 Proxy,Spider,Scanner,Intruder,Repeater,Sequencer,Decoder,Comparer等工具模块。通过拦截HTTP/HTTPS的web数据包,充当浏览器和相关应…

机器学习常用Python库安装

机器学习常用Python库安装 作者日期版本说明Dog Tao2022.06.16V1.0开始建立文档 文章目录 机器学习常用Python库安装Anaconda简介使用镜像源配置 Pip简介镜像源配置 CUDAPytorch安装旧版本 TensorFlowGPU支持说明 DGL简介安装DGLLife RDKitscikit-multilearn Anaconda 简介 …

RocketMQ使用

说明:本文介绍RocketMQ的消费模式&消息类型,RocketMQ的安装参考及简单使用,参考:http://t.csdn.cn/BKFPj 消费模式 RocketMQ与RabbitMQ最大的区别在于,RocketMQ是根据消息的Topic锁定消费者的,Topic属…

当不在公司时,如何在外远程登录公司内网OA系统?

在外远程登录公司内网OA系统 文章目录 在外远程登录公司内网OA系统前言1. 打开“远程桌面”选项2. 安装cpolar客户端3. 登录cpolar客户端4. 创建隧道5. 生成公网地址6. 远程连接其他电脑 前言 随着信息化办公的快速推进,很多企业已经用上了OA系统,并且我…

ubuntu上安装mosquitto服务

1、mosquitto是什么 Mosquitto 项目最初由 IBM 和 Eurotech 于 2013 年开发,后来于 2016 年捐赠给 Eclipse 基金会。Eclipse Mosquitto 基于 Eclipse 公共许可证(EPL/EDL license)发布,用户可以免费使用。作为全球使用最广的 MQTT 协议实现之一 &#x…

Diffusion扩散模型学习4——Stable Diffusion原理解析-inpaint修复图片为例

Diffusion扩散模型学习4——Stable Diffusion原理解析-inpaint修复图片为例 学习前言源码下载地址原理解析一、先验知识二、什么是inpaint三、Stable Diffusion中的inpaint1、开源的inpaint模型2、基于base模型inpaint 四、inpaint流程1、输入图片到隐空间的编码2、文本编码3、…

东芝低导通电阻N沟道MOSFET 为智能穿戴设备赋能

东芝低导通电阻N沟道MOSFET TPN6R303NC,LQ(S 为智能穿戴设备赋能 MOSFET也就是金属-氧化物半导体场效应晶体管,外形与普通晶体管差不多,但具有不同的控制特性,主要是通过充电和放电来切换或放大信号。 此次推出的用于智能穿戴的30V N沟道MO…

CMake的使用--以ORCA避碰C++库为例

1、安装cmake 链接:Download | CMake 版本需下载Binary distributions这个模块下的 Windows x64 Installer: cmake-3.27.1-windows-x86_64.msi 注意事项 1.1勾选为所有用户添加到PATH路径 Add CMake to the system PATH for all users 1.2安装路径建议直接在c…

Dueling Network

Dueling Network —— Dueling Network Architectures for Deep Reinforcement Learning 论文下载地址 论文介绍 图9. Dueling Network 模型结果示意图 Dueling Network与传统DQN的区别在于神经网络结构的不同,Dueling Netowrk在传统DQN的基础上只进行了微小的改动…

python 合并多个excel文件

使用 openpyxl 思路: 读取n个excel的文件,存储在一个二维数组中,注意需要转置。将二维数组的数据写入excel。 安装软件: pip install openpyxl源代码: import os import openpyxl # 将n个excel文件数据合并到一个…

jupyter lab环境配置

1.jupyterlab 使用虚拟环境 conda install ipykernelpython -m ipykernel install --user --name tf --display-name "tf" #例:环境名称tf2. jupyter lab kernel管理 show kernel list jupyter kernelspec listremove kernel jupyter kernelspec re…

微软研究院展示Project Rumi项目;参数高效微调(PEFT)

🦉 AI新闻 🚀 微软研究院展示Project Rumi项目,通过多模态方法增强人工智能理解能力 摘要:微软研究院展示了Project Rumi项目,该项目通过结合文本、音频和视频数据,并采用多模态副语言提示的方法&#xf…

VL 模型 Open-Set Domain Adaptation with Visual-Language Foundation Models 论文阅读笔记

Open-Set Domain Adaptation with Visual-Language Foundation Models 论文阅读笔记 一、Abstract 写在前面 又是一周周末,在家的时间感觉过得很快呀。今天没得时间写博客,留下个标题,明天搞完。 论文地址:Open-Set Domain Adapta…

探索人工智能 | 计算机视觉 让计算机打开新灵之窗

前言 计算机视觉是一门研究如何使机器“看”的科学,更进一步的说,就是指用摄影机和电脑代替人眼对目标进行识别、跟踪和测量等机器视觉,并进一步做图形处理,使电脑处理成为更适合人眼观察或传送给仪器检测的图像。 文章目录 前言…

安全基础 --- https详解 + 数组(js)

CIA三属性:完整性(Confidentiality)、保密性(Integrity)、可用性(Availability),也称信息安全三要素。 https 核心技术:用非对称加密传输对称加密的密钥,然后…