java多线程安全漫谈
1、场景
多线程安全如何定义呢?是对共享变量的修改吗?是不同步吗?设想这些场景
1、我修了一条从自己家里到小镇上的单行道马路,自己一个人开车上下班,购物都不会阻塞。
突然有一天,马路变成公有的了,很多车都在上面开,于是我发现经常迎面塞车。
2、我去银行存钱,账户里本来有200w,发现有两个小妹妹,为了搭讪,让她们各自给我账户
存100w。两个小妹妹一查我账户余额,200w,好家伙,小镇上的有钱人呀,于是忍不住和我聊起天。
聊完,都做了一道算术题200w+100w=300w,先后往我账户上写了300w,我接过存单,
百思不得其解,确实都给我存了100w, 算术题也没毛病,为啥我的账户上只有300w?难道撩一下妹
就损失100w?
进入正题
上面两个场景,是引入多线程后存在两个主要问题。
- 线程间相互竞争有限资源,带来了死锁问题。
- 多个线程对于共享变量操作,执行结果不正确。
那么简单来讲,什么是多线程安全?我们发现,在多线程环境下,有些代码,
存在执行结果不一致的情况,并且和我们在单线程的情况下不一样,从结果上看,
它就是不正确的。所以,理解多线程安全,不是一个非黑即白的二元模型,
多线程安全的三个特性
对于代码块,
{
xxx
}
我们要保证它多线程环境下是安全的,有三个点要满足,就是
- 原子性
- 可见性
- 有序性
为什么有这三个特性,这就要理解java线程模型,从底层剖析。理解java的线程模型,我们可以
以从现代计算机硬件架构来对比,真的,了解硬件对对于软件开发有很好的理解作用。以cpu中
的多核心来类比线程。在JMM中,分共享的主内存和线程私有的工作内存,所有计算操作都是
在工作内存中完成的,然后写入主内存。真是线程中存储有副本,所以会出现不一致的情况
volatile和synchronized关键字的理解
1. volatile保证了可见性,但是在很多情况下,依然实现线程不安全的,需要使用syncrhonized同步。
为什么?因为通常我的操作都是复合操作,非原子的,比如
v = v+ 2; // 看着是一句,但是使用原子语句来拆分,则是很多句。
2. volatile修饰的变量,禁止指令重排。
3、volatile要修饰基本类型,修饰对象或者数组,这是保质了其引用的可见性
参考文章
并发编程之多线程线程安全
线程安全,原子性
《深入理解java虚拟机》
日进有功
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义