【Java 多线程】synchronized优化的过程

synchronized 原理

基本特定

  1. 开始时是一个乐观锁,如果锁冲突频繁,就变成悲观锁
  2. 开始是轻量级锁,如果锁被持有的时间比较长,就变成重量级锁
  3. 实现轻量级锁的时候大概率用到自旋锁的策略
  4. 是一种不公平锁
  5. 是一种可重入锁
  6. 不是读写锁

加锁过程

JVM 将 synchronized锁分为 无锁,偏向锁,轻量级锁,重量级锁,会依据情况来进行锁的升级

在这里插入图片描述

  1. 偏向锁

第一个尝试加锁的过程, 优先进入偏向锁状态

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

如果后续没有其他线程来竞争该所, 那么就不用进行其他同步操作了(避免了加锁解锁的开销)

如果后续有其他线程来竞争该所(刚才已经在锁对象中记录了当前锁属于哪个线程了,很容易识别当前申请锁的线程是不是之前记录的线程), 那就取消原来的偏向锁状态, 进入一般的轻量级锁状态


偏向锁本质上相当于"延迟加锁", 能不加锁就加锁, 尽量来避免不必要的加锁开销.

但是该做标记还是得做的, 否则无法区分何时需要真正加锁

  1. 轻量级锁

随着其他线程进入竞争, 偏向锁状态被消除, 进入轻量级锁状态(自适应的自旋锁)

此处的轻量级锁就是 通过CAS来实现

  • 通过CAS检查并更新一块内存(比如 null => 该线程引用)
  • 如果更新成功, 则认为加锁成功
  • 如果更新失败, 则认为锁被占用, 继续自旋式的等待(并不放弃CPU)

自旋操作时一直让CPU空转, 比较浪费CPU资源

因此此处的自旋不会一直持续进行, 而是达到一定的时间/重试次数, 就不在自旋了

也就是所谓的"自适应"

  1. 重量级锁

如果竞争进一步激烈, 自旋不能快速获取到锁状态, 就会膨胀为重量级锁

此处的重量级锁就是指用到内核提供的 mutex

  • 执行加锁操作, 先进入内核态
  • 在内核态判定当前锁时是否已经被占用
  • 如果该锁被占用, 则加锁失败, 此时线程加入锁的等待队列, 挂起, 等待被操作系统唤醒
  • 如果锁没有被占用, 则加锁成功, 此时线程进入锁的等待队列, 挂起, 等待被操作系统唤醒
  • 经历了一系列的沧海桑田, 这个锁被其他线程释放了, 操作系统也想起了这个挂起的线程,于是唤醒这个线程, 尝试重新获取锁

其他的优化操作

锁消除

编译器+JVM 判断锁是否可消除. 如果可以, 就直接消除.

什么是 “锁消除”

在这里插入图片描述
锁粗化

一段逻辑中如果出现多次加锁解锁, 编译器 + JVM 会自动进行锁的粗化.

在这里插入图片描述

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

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

相关文章

信捷PLC XD3/XD5系列通过网口或串口如何实现远程上下载程序?

信捷PLC是一种可编程逻辑控制器,广泛应用于工业自动化领域。它具有高可靠性、灵活性和可编程性的特点,可以用于监控和控制各种生产设备。信捷PLC的远程控制和程序上下载可以通过网关实现。 而PLC远程透传网关是博达智联针对目前自动化行业内客户需求多变…

Tomacat下载并且手动自动部署Web项目

Tomacat下载并且手动自动部署Web项目 Tomcat的简介Tomcat的作用Tomcat的下载Tomcat 部署1、环境准备2、手动部署项目3、自动部署项目(IDEA) ⭐ 前言 ⭐ 本篇文章主要介绍 Tomacat下载部署Web项目的详细使用以及部分理论知识 Tomcat的简介 Tomcat 服务…

logistic回归分析

结局变量:二分类(常见)或多分类变量研究一个或多个原因变量和结果变量的因果关系 eg:Y必须是分类变量

html--钢琴

代码 <!DOCTYPE html> <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetutf-8" /> <title>html钢琴</title> <script src"js/js.js"></script> <link href"…

寄存器(内存访问)

文章目录 寄存器&#xff08;内存访问&#xff09;1 内存中字的存储2 DS和[address]3 字的传送4 mov、add、sub指令5 数据段6 栈7 CPU提供的栈机制8 栈顶超界的问题9 push、pop指令10 栈段 寄存器&#xff08;内存访问&#xff09; 1 内存中字的存储 CPU中&#xff0c;用16位寄…

Nginx的日志怎么看,在哪看,access.log日志内容详解

Nginx 的日志文件通常位于服务器的文件系统中&#xff0c;具体位置可能因配置而异。以下是查看 Nginx 日志的几种方法&#xff1a; 1、查看访问日志&#xff1a;在默认配置下&#xff0c;Nginx 的访问日志文件路径为 /var/log/nginx/access.log。您可以通过命令 sudo cat /var…

python第一次作业

第一天&#xff1a; 1、写一篇博客&#xff0c;说明window系统中如何安装和配置python环境 1.开发环境&#xff1a; 记事本工具&#xff1a;记事本、vim、sublime、vscode…… IDE&#xff08;集成开发环境&#xff09;&#xff1a;pycharm 在电脑自带的应用商店下载&…

L1-5 猜帽子游戏

宝宝们在一起玩一个猜帽子游戏。每人头上被扣了一顶帽子&#xff0c;有的是黑色的&#xff0c;有的是黄色的。每个人可以看到别人头上的帽子&#xff0c;但是看不到自己的。游戏开始后&#xff0c;每个人可以猜自己头上的帽子是什么颜色&#xff0c;或者可以弃权不猜。如果没有…

安卓studio安装(从安装到配置到helloworld)

安卓studio安装 2024.3.11官网的版本&#xff08;有些翻墙步骤下载东西也解决了&#xff09; 这次写的略有草率&#xff0c;后面会更新布局的&#xff0c;因为截图量太大了&#xff0c;有需要的小伙伴可以试着接受一下哈哈哈哈 进入官网下载&#xff1a; https://www.bing.com…

CESlurl-HPEVirtual UserGenerator-Web-HTTP/HTML操作

前置条件 操作环境&#xff1a;VMwareWorkstation虚拟机 Windows10x64 IE浏览器设置&#xff1a;&#xff08;避免浏览器升级&#xff09; 操作软件&#xff1a;Virtual User Generator 打开“小飞机” Virtual User Generator操作步骤&#xff1a;

学习JAVA的第二十一天(基础)

多线程 线程&#xff1a; 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。 进程&#xff1a; 程序的基本执行实体 并发&#xff1a; 在同一时刻&#xff0c;有多个指令在单个CPU上交替执行 并行&#xff1a; 在同一时刻&…

专升本 C语言笔记-03 变量的作用域

1.变量的概念 内存中有个存储区域,这个地方的数据可以在同一类型范围内不断变化通过变量名,可以访问这块内存区域,获取里面的值; 变量名的构成:数据类型 变量名 值 C语言中变量声明格式: 数据类型 变量名 值 2.变量的注意 2.1.全局变量: 定义在函数外部的叫全局变量…