synchronized的优化策略^o^

synchronized 特点:
  • 开始是乐观锁,如果锁冲突,就转换为悲观锁
  • 开始是轻量级锁,如果锁被持有的时间较长,就转换为重量级锁
  • 实现轻量级锁的时候大概率用到的是自旋锁策略
  • 是一种不公平锁
  • 是一种可重入锁
  • 不是读写锁
synchronized 加锁过程:

JVM 将 synchronized 锁分为 无锁、偏向锁、轻量级锁、重量级锁 状态。会根据情况,进行依次升级。
在这里插入图片描述

  • 1,无锁
    顾名思义:就是没有加锁,这对于synchronized 这个加锁操作来说是不是很扯,其实啊它和乐观锁有点相似,乐观锁也是最初是直接尝试访问数据,并没有加锁,如果检测到锁冲突(其他线程来竞争锁),才会转换成悲观锁。
  • 2,偏向锁
    这个锁很厉害:首先一个线程会对该锁进行标记,来表示它已经占有了这个锁,但是实际上它并没有加锁,如果此时还有其他线程来竞争这把锁,该线程就会真正获取到锁。偏向锁本质上相当于 “延迟加锁” . 能不加锁就不加锁, 尽量来避免不必要的加锁开销.但是该做的标记还是得做的, 否则无法区分何时需要真正加锁.
  • 3,自旋锁(轻量级锁)
    随着其他线程进⼊竞争, 偏向锁状态被消除, 进⼊轻量级锁状态(⾃适应的⾃旋锁).
    此处的轻量级锁就是通过 CAS 来实现.
    • 通过 CAS 检查并更新⼀块内存 (⽐如 null => 该线程引⽤)
    • 如果更新成功, 则认为加锁成功
    • 如果更新失败, 则认为锁被占⽤, 继续⾃旋式的等待(并不放弃 CPU).
      ⾃旋操作是⼀直让 CPU 空转, ⽐较浪费 CPU 资源.
      因此此处的⾃旋不会⼀直持续进⾏, ⽽是达到⼀定的时间/重试次数, 就不再⾃旋了.也就是所谓的 “⾃适应”
  • 重量级锁
    如果竞争进一步激烈,自旋不能快速获取到锁状态,就会膨胀为重量级锁,此处的重量级锁就是指用到内核提供的mutex
    • 执行加锁操作,先进入内核态
    • 在内核态判定当前锁是否已经被占用
    • 如果该锁没有被占用,则加锁成功,并切换回用户态
    • 如果该锁被占用,则加锁失败,此时线程进入锁的等待队列,挂起,等待被操作系统唤醒
    • 经历了一系列的沧海桑田,这个锁被其他线程释放了,操作系统也想起了这个挂起的线程,于是唤醒这个线程,尝试重新获取锁。
    其他优化操作

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

有些应⽤程序的代码中, ⽤到了 synchronized, 但其实没有在多线程环境下. (例如 StringBuffer)

StringBuffer sb = new StringBuffer();
sb.append("a");
sb.append("b");
sb.append("c");
sb.append("d");

此时每个 append 的调⽤都会涉及加锁和解锁. 但如果只是在单线程中执⾏这个代码, 那么这些加锁解锁操作是没有必要的, 白白浪费了⼀些资源开销.

锁粗化:⼀段逻辑中如果出现多次加锁解锁, 编译器 + JVM 会⾃动进⾏锁的粗化.

举个例子:假如,你和领导汇报工作,汇报三件事
我们知道两个人在通话中第三个人是不能插进来的,这也和加锁很相似。
如果你打三次电话,分三次汇报这三件事,我相信领导在接到你的第三次电话的时候,很可能就想亲切地问候你一下了。
但是如果你一次电话就将这三件事汇报完,不仅能得到领导的表扬,还能节省自己的时间。
上诉案例,你将多次加锁完成的事,都堆加在一块只用一次加锁就完成,这样的操作我们称为 “ 锁粗化 ”

相关题目
    1. 什么是偏向锁?
      偏向锁不是真正的加锁,而是在锁对象中记录一个标记,如果没有其他线程参与竞争,那么就不会真正执行加锁操作,从而降低程序开销,一旦真的涉及到其他的线程竞争,再取消偏向锁状态,进入轻量级锁状态。
    1. synchronized 实现原理 是什么?
    • 开始是乐观锁,如果锁冲突,就转换为悲观锁
    • 开始是轻量级锁,如果锁被持有的时间较长,就转换为重量级锁
    • 实现轻量级锁的时候大概率用到的是自旋锁策略
    • 是一种不公平锁
    • 是一种可重入锁
    • 不是读写锁
    • synchronized的加锁过程是:无锁 -> 偏向锁 -> 自旋锁 -> 重量级锁
    • 之后再按照我们上面讲的,再一 一介绍一下这几种状态就行了

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【考研数学】《1800》《660》《880》如何选择及搭配?看这一篇!

可以刷880!但一定要把心态稳住!!! 我考研的时候刷880前几章还可以,越往后越刷不动 因为很多人在备考前两轮的后期听课和刷题都不如前几章细心...越往后知识点掌握的越来越不熟练,所以也建议大家在前几轮复…

Kafka复习

消息中间件的作用: 异步处理: 与并行相比,虽然减少了时间,但是还是得等待其他线程执行完,但是消息中间件对于简单的业务处理,还要引入一个中间件也比较复杂如果我投递了简历之后需要发送成功邮件以及短信,就可以交给消息中间件就像数据库、redis数据一致性,需要用到延迟…

VScode使用记录

代码颜色是白色 发现没有根据对应的文本类型显示颜色 解决方法: 效果:

「sentinel」流量控制组件的应用

「sentinel」流量控制组件的应用 Sentinel版本QPS 一、初识Sentinel1、Sentinel2、Sentinel 和 Hystrix对比3、雪崩问题 二、环境搭建1、下载安装Sentinel2、微服务整合Sentinel 三、流量控制1、簇点链路2、流控设置3、流控模式直接关联链路 4、流控效果流控效果解释 四、热点限…

线性表的链式存储(循环链表)

文章目录 前言一、循环链表是什么?二、循环链表的操作实现总结 前言 T_T此专栏用于记录数据结构及算法的(痛苦)学习历程,便于日后复习(这种事情不要啊)。所用教材为《数据结构 C语言版 第2版》严蔚敏。有关…

Codeforces Round 939 (Div. 2) A~E

A.Nene’s Game(循环) 题意: 妮妮发明了一种基于递增序列 a 1 , a 2 , … , a k a_1,a_2,\ldots,a_k a1​,a2​,…,ak​的新游戏。 在这个游戏中,最初 n n n个玩家排成一排。在这个游戏的每一轮中,都会发生以下情况…

详解SPI通信协议以及FPGA实现

文章目录 一、SPI简介二、SPI通信结构三、多从机模式四、时钟极性(CPOL)和时钟相位(CPHA)五、SPI通信过程六、实现SPI主机发送程序6.1 波形图分析6.2 Verilog代码6.3 发送数据控制模块6.4 仿真代码编写以及仿真结果分析 七、Veril…

Kubernetes Pod的配置管理 ConfigMap和Secret

目录 前言 一、为什么需要配置管理 二、使用ConfigMap管理Pod的配置信息 2.1 创建ConfigMap(4种方式) 2.1.1 指定ConfigMap的参数创建 2.1.2 指定配置文件创建ConfigMap 2.1.3 通过一个文件内的多个键值对创建ConfigMap 2.1.4 yaml文件创建Config…

Android 性能优化(七):APK安装包体积优化

包体积优化重要性 移动 App 特别关注投放转化率指标,而 App 包体积是影响用户新增的重要因素,而 App 的包体积又是影响投放转化率的重要因素。 Google 2016 年公布的研究报告显示,包体积每上升 6MB 就会带来下载转化率降低 1%, …

114 接口中幂等性的保证

前言 同样是 面试问题 如何确保接口的 幂等性 幂等是一个 较为抽象的概念, 多次重复访问, 不会导致业务逻辑的异常 这里从增删改查, 几个方面列一下 一般来说, 我们核心需要关注的就是 新增 和 更新 对于 增加元素, 首先针对唯一约束进行校验, 然后再处理新增的相关业…

二刷大数据(三)- Flink1.17

目录 Flink概念与SparkStreaming区别分层API 工作流程部署模式**Local Mode****Standalone Mode****YARN Mode****Kubernetes Mode****Application Mode** 运行架构stand alone 核心概念算子链任务槽 窗口窗口**窗口的目的与作用****时间窗口(Time Windows&#xff…

vue3中web前端JS动画案例(一)

上述案例主要使用定时器&#xff0c;和绝对定位产生动画 <script setup> import { ref, onMounted, watch } from vue // ----------------------- 01 js 动画介绍--------------------- // 1、匀速运动 // 2、缓动运动&#xff08;常见&#xff09; // 3、透明度运动 //…

抖店底层逻辑,关于5个“为什么”的答案~

我是王路飞。 很多人对抖店的底层逻辑有一种抗拒心态&#xff0c;不想学习和了解。 认为做抖店不就是开店卖货嘛&#xff0c;什么火、什么有热度卖什么就好了&#xff0c;了解那么多“理论知识”有什么用呢&#xff1f; 但往往正是这些基础理论&#xff0c;底层逻辑&#xf…

Linux系统一键安装DataEase结合内网穿透实现公网访问本地WebUI界面

文章目录 前言1. 安装DataEase2. 本地访问测试3. 安装 cpolar内网穿透软件4. 配置DataEase公网访问地址5. 公网远程访问Data Ease6. 固定Data Ease公网地址 前言 DataEase 是开源的数据可视化分析工具&#xff0c;帮助用户快速分析数据并洞察业务趋势&#xff0c;从而实现业务…

PMM2 MySQL监控管理工具

目录 1. PMM介绍 2. 安装PMM服务端 2.1 安装docker 2.1.1 下载docker 2.1.2 上传docker包 2.1.3 启动守护进程 2.1.4 查看docker状态 2.2 安装PMM 2.2.1 下载镜像 2.2.2 load镜像 2.2.3 查看镜像 2.2.4 创建容器 2.2.5 运行镜像 2.2.6 验证PMM服务器 2.2.7 删除…

MySQL行格式(row format)

MySQL行格式&#xff08;row format&#xff09; 表的行格式决定了其行的物理存储方式&#xff0c;这反过来又会影响查询和 DML 操作的性能。随着单个磁盘页面容纳更多行&#xff0c;查询和索引查找可以更快地工作&#xff0c;缓冲池中需要的高速缓存内存更少&#xff0c;写出…

【进阶六】Python实现SDVRPTW常见求解算法——离散粒子群算法(DPSO)

基于python语言&#xff0c;采用经典离散粒子群算法&#xff08;DPSO&#xff09;对 带硬时间窗的需求拆分车辆路径规划问题&#xff08;SDVRPTW&#xff09; 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整2.1 需求拆分2.2 需求拆分后的服务时长取值问题 3. 求解结果4. …

.netcore+vue新生分班系统的设计与实现

.netcore vue新生分班系统的设计与实现说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 主要技术&#xff1a; 基于.net core架构和mysql数据库vue 东北石油大学新生分班系统的设计与实现 功能模块&#xff1a; 登录 注册学生 忘记密码 系统首顶 个…

fatal error C1001: An internal error has occurred in the compiler

VS2008驱动项目A&#xff0c;集成一个Wzarid生成的驱动LIB项目B&#xff0c;在编译64位驱动时,出现以下错误&#xff1a; 1>------ Build started: Project: xxxx, Configuration: Release x64 ------ 1>Linking... 1>fatal error C1001: An internal error has occu…

AI时代下,普通人能怎么做?

AI玩法千千万&#xff0c;你已经知道了多少呢&#xff1f;是否已经实践起来&#xff1f; 大家好&#xff0c;我是程序员影子 | 全网同名 一名致力于帮助更多朋友快速入门编程的程序猿 今天&#xff0c;我将以小白入门的视角带着大家了解一下目前火热的AI实践玩法&#xff1b…