线程安全之Java内存模型

Java中的内存模型

包括三部分: 线程, 工作内存(本地内存),主内存

JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式。
JMM是隶属于JVM的。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(Main Memory)中,每个线程都有一个私有的本地内存(Local Memory)

1、主内存中存放着变量, 这里的变量是指一些实例数据, 静态变量及代码, 对于方法变量,局部变量为线程私有

2、工作内存:----中存储了该线程以读/写共享变量的副本
工作内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存、写缓冲区、寄存器以及其他的硬件和编译器优化。

3、对于变量的读写操作必须在线程自己的工作内存中进行操作,而不同线程之间的通信,线程间变量值的传递均需要在主内存来完成。

工作内存和主内存之间的交互

主要有8步(也可简化成4步)
lock ---- 锁定,操作于主内存,声明此变量多线程情况下只允许一个线程访问,在对象头中添加锁信息
unlock ----操作于主内存, 释放锁资源
read ---- 操作于主内存中,将主内存的变量值读出
load ---- 装载,操作工作内存中,将主内存的变量装载出,以供工作内存使用
use ---- 使用,操作于工作内存中,将变量的值交给执行引擎
assign ----赋值,操作于工作内存中,由执行引擎将 值 赋 给变量
store ---- 存储,操作于工作内存中,将把工作内存中一个变量的值传送到主内存
write ---- 操作于主内存,将值写入 主内存
简化的四步
read load store write

JMM的三个特性

1、原子性(Atomic)
是指: 对共享内存的操作必须是要么全部执行直到执行结束,且中间过程不能被任何外部因素打断,要么就不执行。被称为原子性。

2、可见性()
是指: 多线程在自己的工作内存操作共享内存的副本时,执行结果后能够及时的同步到共享内存,确保其他线程对此结果及时可见。

3、有序性()
我们首先要知道程序的执行顺序按照代码顺序执行,在单线程环境下,程序的执行都是有序的,
但是在多线程环境下,JMM 为了性能优化,编译器和处理器会对指令进行重排-----乱序执行优化,程序的执行会变成无序。

指令重排的意义:可以保证串行语义一致,但是没有义务保证多线程间的语义一致,对于提高CPU处理性能是十分重要的

但是在 JVM内部有些指令是不能重排的,了解一下 Happens-Before原则(先行发生原则)

  • 程序顺序原则:一个线程内保证语义的串行性

  • volatile规则:volatile 变量的写,先发生于读,这保证了volatile变量的可见性

  • 锁规则:解锁(unlock)必然发生在随后的加锁(lock)前

  • 传递性:A先于B,B先于C,那么A必然先于C

  • 线程的start()方法先于它的每一个动作

  • 线程的所有操作先于线程的终结(Thread.join())

  • 线程的中断(interrupt())先于被中断线程的代码

  • 对象的构造函数执行,结束先于finalize() 方法

结语

JMM的三大特性,有效的保证了多线程之间的通信规则,防止了脏数据的出现,对于去保证线程安全提供了思路。

关于volatile及synchronized 语义,及如何从jmm的三大特性来保证线程安全下一章节会讲。
[本文链接]:https://editor.csdn.net/md?articleId=106492089

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值