线程安全定义:从原子性、可见性、有序性三个维度评估一个类是否具备高并发安全性

阿强姑娘_1854

阿强姑娘_1854

2026-05-24

581人浏览

原创

线程安全指多线程并发访问时类总能表现正确行为,核心依赖原子性(操作不可分割)、可见性(修改及时被见)、有序性(指令不乱序)三者协同保障。

线程安全定义:从原子性、可见性、有序性三个维度评估一个类是否具备高并发安全性

一个类是否线程安全,不能只看它“能不能跑起来”,关键要看它在多线程高并发下能否始终给出确定、一致、可预期的结果。Java中对线程安全的正式定义是:当多个线程访问某个类时,无论运行时环境如何调度、线程如何交替执行,只要调用方无需额外同步措施,该类总能表现出正确行为。这个“正确行为”的底层支撑,正是原子性、可见性、有序性三者协同保障的结果。

原子性:操作不被拆开,也不被插队

原子性解决的是“执行中途会不会被干扰”的问题。比如 i++ 看似一条语句,实际包含读值、加1、写回三步——若两个线程同时执行,就可能都读到旧值、都加1、都写回,最终只+1而非+2。

  • 基础类型单次读/写(如 int a = 5;)默认具备原子性;但复合操作(++、+=、对象引用赋值除外)不是原子的
  • 用 synchronized 或 ReentrantLock 可以把一段逻辑打包成原子块
  • 推荐优先使用 AtomicInteger、AtomicReference 等原子类,它们基于CAS实现无锁原子更新,性能更优
  • 注意:volatile 不能保证原子性,它只管“读写本身不拆”,不管“读-改-写”整套流程

可见性:改了就得让别人马上知道

可见性解决的是“我改了,你能不能立刻看到”的问题。由于JVM有工作内存与主内存之分,线程常缓存变量副本,导致一个线程更新后,另一个线程还在用旧值循环或计算。

  • 典型表现:flag 控制循环的线程永远不退出(如 while(flag) 中 flag 被另一线程设为 false 却不生效)
  • volatile 是最轻量级的可见性保障手段,它强制每次读取都从主内存加载、每次写入都立即刷回主内存
  • synchronized 和 Lock 在加锁释放时,也隐含“清空本地缓存 + 刷新主内存”的语义,因此同样保证可见性
  • 普通变量没有这些机制,修改可能长期滞留在某个线程的工作内存中

有序性:代码顺序 ≠ 执行顺序,但关键依赖不能乱

有序性解决的是“指令会不会被重排,导致逻辑错乱”的问题。编译器、JIT、CPU 都可能为优化性能调整指令顺序,只要不影响单线程结果。但在多线程下,这种重排可能破坏依赖关系。

  • 常见陷阱:对象初始化未完成,引用就被其他线程拿到并使用(如 instance = new Singleton() 可能被重排为“分配内存→设置引用→初始化对象”,导致拿到半初始化对象)
  • volatile 写操作具有“禁止指令重排序”的效果,能防止其前后的代码被重排到 volatile 写之后
  • synchronized 块内指令不会被重排到块外,且进入/退出时遵循 happens-before 规则,天然保障有序性
  • 双重检查锁(DCL)单例必须给 instance 加 volatile,否则无法阻止构造过程重排

判断一个类是否真正线程安全,就要逐项核验:共享状态的读写有没有竞态(原子性)、修改能否及时同步(可见性)、关键步骤是否存在被重排风险(有序性)。三者缺一不可,任一缺失都可能在压测或上线后偶然爆发,极难复现和定位。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

2023.08.10

3938

6

PixTV官网入口地址合集
PixTV官网入口地址合集

本专题汇总了 PixTV AI 一站式视频创作平台的官方入口与使用教程。无需下载软件,浏览器直接访问即可使用。平台将剧本、图像、视频、声音与剪辑整合在“无限画布”中,接入 GPT Image 2.5、Seedance 2.5 等头部模型。本专题整理了从新建画布、角色锚定、分镜拆分到视频生成与导出的完整操作指南,助你快速上手 AI 短剧与漫剧创作。

2026.10.10

0

15

Kratos框架HTTP与gRPC服务开发教程
Kratos框架HTTP与gRPC服务开发教程

本专题围绕Kratos框架双协议服务开发,涵盖HTTP路由与处理器编写、参数获取、gRPC服务实现与客户端调用、metadata上下文传递、encoding编解码注册、统一响应封装、超时控制与流式响应实现方法。

2026.10.10

0

15

Kratos框架Protobuf接口定义与代码生成合集
Kratos框架Protobuf接口定义与代码生成合集

本专题讲解Kratos框架接口定义体系,涵盖proto编写规范、proto add/client/server生成命令、http注解路由、validate校验、OpenAPI文档生成、跨服务proto复用与兼容性设计。

2026.10.10

0

15

C++虚函数怎么定义和调用
C++虚函数怎么定义和调用

C++虚函数是实现运行时多态的重要机制。本专题从virtual关键字的基本用法入手,介绍基类与派生类之间的函数重写、基类指针调用派生类方法,以及动态绑定的执行过程,帮助初学者掌握虚函数的核心语法。

2026.10.10

0

26

C++类与对象的封装方法教程
C++类与对象的封装方法教程

C++封装是面向对象编程的核心特性之一,通过类将数据与操作数据的函数组织在一起,并利用访问权限控制外部访问。本专题介绍类的定义、成员变量、成员函数以及public、private和protected的使用方法,帮助初学者掌握封装的基本原理。

2026.10.10

0

32

C++构造函数定义与调用方法
C++构造函数定义与调用方法

C++构造函数用于初始化类对象,是面向对象编程的重要基础。本专题从构造函数的定义、声明和调用入手,介绍默认构造函数、带参数构造函数、拷贝构造函数及成员初始化列表,帮助初学者掌握对象创建与初始化的基本方法。

2026.10.10

20

16

Kratos框架零基础入门教程
Kratos框架零基础入门教程

本专题整理Kratos框架入门内容,涵盖Go环境准备、kratos CLI安装升级、new命令创建项目、目录结构分层说明、服务启动与双协议端口、依赖下载报错排查,帮助开发者快速跑通第一个Kratos框架微服务应用。

2026.10.10

0

15

C++条件判断语句怎么写
C++条件判断语句怎么写

C++条件判断是控制程序执行流程的重要基础。本专题介绍if、if-else、else if和switch等常见分支语句,结合条件表达式、比较运算符与代码示例,帮助初学者掌握不同场景下的判断逻辑。

2026.10.10

0

13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.4万人学习