Java内存模型

Java内存模型不是Java内存区域划分!Java内存模型专注于内存交互、变量读取;而Java内存区域划分专注于JVM内存按功能不同进行划分。

概念定义:

这是JVM运行的计算机的硬件级别的示意图:

JVM本身屏蔽掉了硬件、操作系统的差异,所以不管你的硬件、操作系统是什么样子的,JVM会兼容所有硬件、操作系统,向上抽象出来一个抽象模型:Java内存模型。

先来一张简单的Java内存模型概念图:

这张图反应了Java内存模型中,各块内存是如何进行交互的。

再来一张复杂的Java内存模型概念图:

这张图描述了一个变量是如何进行读取的、是如何进行写入的。图上表注的8个操作均为最小粒度的操作,即机器码指令。因其执行过程中不会被其他线程打断,所以是原子操作。

原子性、可见性、有序性:

Java内存模型把注意点放在了如何实现线程安全上。在多个线程同时在这个内存模型上执行的时候,如何保证数据被正确地读取、修改,所以规定了三个原则:原子性、可见性、有序性。只要满足了这三个原则,便可以实现线程安全(所谓的线程安全,就是说变量在多线程环境下的正确读取、修改)。

原子性:

定义:即一个操作或多个操作,要么全部执行并且执行过程中不会被任何因素打断,要么就不执行。

由 Java 内存模型来直接保证的原子性变量操作包括 read、load、assign、use、store 和 write。大致可以认为基本数据类型的读取、赋值操作是原子性的。

同时 lock 和 unlock 可以保证更大范围操作的原子性,但lock、unlock是机器码层面的,对应在字节码上便是monitorenter 和 monitorexit,对应在代码层面便是: synchronized

可见性:

定义:可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。表现为一个变量的值在多个线程的工作内存中是始终是一致的。

volatile变量被一个线程修改之后,修改后的值会立刻同步至主内存,同时其他线程中如果使用了这个值,将会立刻失效,下一次使用时需要重新从主内存中获取。

synchronized同步块的可见性是由“对一个变量执行 unlock 操作之前,必须先把此变量同步回主内存中( store、write 操作)”这条规则获得。

有序性:

定义:即程序执行的效果和按照代码的先后顺序执行的效果相同。

为什么会有这么一说?难道不是按照代码先后顺序来执行?是的,实际上执行的时候,并不是按照代码书写的顺序来执行的:为了指令执行得更高效,编译器、指令器会进行重排序。编译器是JVM层面的,是对java代码语句进行编译时的重排序;指令器是硬件层面的,是对机器指令执行时的重排序。

同时为了保证执行效果相同,不能随便想怎么重排序就怎么重排序,所以规定了Happens Before原则,并且通过一些底层机制来保证Happens Before原则,来限制编译器、指令器对代码的重排序,从而保证了有序性

有序性不是仅仅针对线程安全问题才有意义的,有序性保证了线程开启在线程结束之前、保证了对象初始化在对象finalize()之前等等。

针对线程安全的有序性而言,对于串行的线程,指令重排序不会影响线程安全;对于并行线程,就需要考虑是否需要用volatile来修饰变量来保证线程安全了。

如果在被线程内观察,所有操作都是有序的;如果在一个线程中观察另一个线程,所有操作都是无序的。前半句指“线程内表现为串行的语义”,后半句是指“指令重排”现象和“工作内存与主内存同步延迟”现象。

Java 语言通过 volatile 和 synchronized 两个关键字来保证线程之间操作的有序性:

volatile 底层机制是通过内存屏障来保证Happens Before原则; 

synchronized 则是由“一个变量在同一时刻指允许一条线程对其进行 lock 操作”这条规则获得,这条规则决定了持有同一个锁的两个同步块只能串行的进入,既然同一个时间只有一个线程在执行,那么便是“线程内表现为串行的语义”,所以不会出现有序性的问题。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值