深入理解Java虚拟机-线程安全与锁优化
线程安全级别
| 级别 | 描述 | 示例 |
|---|---|---|
| 不可变(Immutable) | 对象状态不可变,天然线程安全。 | String、Integer |
| 绝对线程安全 | 所有操作都线程安全(Java 中极少见)。 | Vector(通过同步实现,但复合操作仍不安全) |
| 相对线程安全 | 单次操作线程安全,复合操作需同步。 | Collections.synchronizedList() |
| 线程兼容 | 需调用方通过同步保证安全。 | ArrayList |
| 线程对立 | 无论是否同步都无法保证安全(设计错误)。 | 未正确同步的共享变量 |
线程安全的实现方式
互斥同步(Mutual Exclusion)
核心机制:通过锁(如
synchronized、ReentrantLock)保证临界区代码的原子性底层原理:
synchronized:基于对象头中的 Mark Word 和 Monitor 锁实现
// HotSpot 虚拟机对象头(64位)
Mark Word (64 bits): [锁状态标志 | 线程ID | 分代年龄 | ...]
锁状态:无锁 → 偏向锁 → 轻量级锁 → 重量级锁
ReentrantLock:基于 AQS(AbstractQueuedSynchronizer) 实现,支持公平/非公平锁
非阻塞同步(Non-Blocking)
- 核心机制:通过 CAS(Compare-And-Swap) 实现无锁编程
- CAS 指令:
AtomicInteger、AtomicReference等类的底层实现 - ABA 问题:通过
AtomicStampedReference解决 - 硬件支持:x86 架构的
cmpxchg指令
锁优化策略
偏向锁(Biased Locking)
- 目的:减少无竞争场景下的同步开销
- 原理:记录首个获取锁的线程 ID,后续该线程无需 CAS 操作即可直接进入临界区
- 适用场景:单线程重复访问锁
- 参数:
-XX:+UseBiasedLocking(默认开启)
轻量级锁(Lightweight Locking)
- 目的:减少多线程轻度竞争时的锁开销
- 原理:通过 CAS 操作将对象头替换为线程栈指针,避免操作系统级阻塞
- 适用场景:低并发竞争(如两个线程交替访问)
自旋锁(Spin Lock)
- 目的:减少线程阻塞和唤醒的上下文切换开销
- 原理:线程在竞争锁时循环等待(自旋),而非立即挂起
- 参数:
-XX:PreBlockSpin=10(默认自旋 10 次后升级为阻塞)
锁消除(Lock Elimination)
- 目的:去除无实际竞争场景下的冗余锁
- 原理:JIT 编译器通过 逃逸分析,若发现锁对象仅被当前线程使用,直接删除锁操作
锁粗化(Lock Coarsening)
- 目的:减少频繁加锁/解锁的开销
- 原理:合并多个连续的锁操作为一个更大的锁范围
适应性自旋(Adaptive Spinning)
- 目的:动态调整自旋策略,平衡 CPU 资源消耗
- 原理:根据历史自旋成功率和锁持有时间,动态调整自旋次数或直接阻塞
重量级锁(Heavyweight Locking)
- 目的:解决高并发竞争下的线程安全
- 原理:依赖操作系统互斥量(mutex)和条件变量(condition variable),直接阻塞竞争线程
- 适用场景:多线程高竞争(如秒杀场景)
深入理解Java虚拟机-线程安全与锁优化的更多相关文章
- Java虚拟机--线程安全和锁优化
Java虚拟机--线程安全和锁优化 线程安全 线程安全:当多线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象 ...
- 深入理解JVM(7)——线程安全和锁优化
Java中的线程安全 按照线程安全的“安全程度”由强至弱来排序,可以将Java语中各种操作共享的数据分为以下5类:不可变. 绝对线程安全. 相对线程安全. 线程兼容和线程对立. 1.不可变 不变的对象 ...
- JVM之java并发 ——线程安全与锁优化
概述 人们很难想象现实中的对象在一项工作进行期间,会被不停地中断和切换,对象的属性(数据)可能会在中断期间被修改和变“脏”,而这些事情在计算机世界中则是很正常的事情.有时候,良好的设计原则不得不向现实 ...
- 深入理解Java虚拟机(九)——后端编译与优化
即时编译器 Java程序最初都是通过解释器进行执行,当发现某个方法或者代码块被运行得非常频繁,这些代码就被认为是热点代码,为了提高这些代码得运行效率,虚拟机会把热点代码编译成本地机器码,并进行优化,运 ...
- 深入理解java虚拟机(7)---线程安全 & 锁优化
关于线程安全的话题,足可以使用一本书来讲解这些东西.<Java Concurrency in Practice> 就是讲解这些的,在这里 主要还是分析JVM中关于线程安全这块的内容. 1. ...
- 深入理解java虚拟机-第13章-线程安全与锁优化
第十三章 线程安全与锁优化 线程安全 java语言中的线程安全 1 不可变.Immutable 的对象一定是线程安全的 2 绝对线程安全 一个类要达到不管运行时环境如何,调用者都不需要额外的同步措施, ...
- 《深入理解Java虚拟机》-----第13章 线程安全与锁优化
概述 在软件业发展的初期,程序编写都是以算法为核心的,程序员会把数据和过程分别作为独立的部分来考虑,数据代表问题空间中的客体,程序代码则用于处理这些数据,这种思维方式直接站在计算机的角度去抽象问题和解 ...
- 【深入理解JAVA虚拟机】第5部分.高效并发.2.线程安全和锁优化
1 概述 对于这部分的主题“高效并发”来讲,首先需要保证并发的正确性,然后在此基础上实现高效. 2 线程安全 <Java Concurrency In Practice> 的作者Brian ...
- 深入理解Java虚拟机(第三版)-14. 线程安全与锁优化
14. 线程安全与锁优化 1. 什么是线程安全? 当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替进行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个 ...
- 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化
<深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...
随机推荐
- 深⼊mysqlONDUPLICATEKEYUPDATE语法的分析
深⼊mysqlONDUPLICATEKEYUPDATE语法的分析mysql "ON DUPLICATE KEY UPDATE" 语法如果在INSERT语句末尾指定了ON DUPLI ...
- flutter run出现 Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
1 今天flutter run出现下面这样的情况 > Task :prepareKotlinBuildScriptModel UP-TO-DATE Deprecated Gradle featu ...
- docker上安装并启动redis
//查看镜像 [root@VM-0-3-centos ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEredis latest cc69ae1 ...
- Windows下安装和配置Java JDK
1.下载地址 JDK21 Windows安装版下载地址:https://www.oracle.com/java/technologies/downloads/#jdk21-windows JDK21 ...
- SqlServer性能检测之Sql语句排查
很多时候,我们在用SQL语句查询数据时,难免会漏掉对SQL语句性能的考虑,所以有时就会造成SqlServer服务占用过高的问题,为了大致排查是哪些SQL语句造成的问题,我们可以通过如下SQL查询出最近 ...
- [业界方案] ClickHouse业界解决方案学习笔记
[业界方案] ClickHouse业界解决方案学习笔记 目录 [业界方案] ClickHouse业界解决方案学习笔记 0x00 摘要 0x01 简介 0x02 OLAP场景的特点 0x03 选型原因 ...
- last和history 查看登录和操作命令
last命令 last命令:用于显示用户最近登录信息.单独执行last命令,它会读取/var/log/wtmp的文件,并把该文件的内容记录的登入系统的用户名单全部显示出来. 语法 last(选项)(参 ...
- druid 连接池参数说明
一.参数配置说明 属性 说明 建议值 url 数据库的jdbc连接地址.一般为连接oracle/mysql.示例如下: mysql : jdbc:mysql://ip:port/dbname? ...
- 微信小程序之java服务端获取openid
微信小程序越来越热,最近团队写了一个小程序,这篇博客我将讲一下怎么通过java服务端获取到用户的openid. api文档的授权登陆地址: http://developers.weixin.qq.co ...
- 在Android源码中为APK编译系统权限
系统权限获取 打包为APK进行系统签名 对于 部分功能的访问需要使用到系统权限,需要 添加 android:sharedUserId="android.uid.system" 权限 ...