读后感,多半错误。
volatile前提名词理解:
共享内存:对于每个线程都是共享的存储区域
-------------就是堆内存(所有实例域、静态域、数组元素都存储在堆内存中,统称共享变量)
本地内存:每个线程私有的存储区域,其它线程,不可见
-------------本地内存在物理上指缓存、写缓冲区、寄存器等存储器
-------------本地内存用于存储线程读写共享变量的副本,目的是为了减少高速cpu和慢速内存i/o之间交互所浪费的时间。
操作内存可见性
------:指的是线程对变量(包含共享变量和共享变量副本)的操作结果对自己程序的之后的操作以及其它线程可见。
------:这说的不是操作之间天然带有可见性,是我们为了程序正确执行,需要想办法让一个操作对其它操作要有可见性。由于本地内存的出现导致操作出现了不可见性
happens-before
------:jdk1.5开始JSR-133内存模型用happens-before来阐述操作之间的可见性
-------:即一个操作结果对另一个操作可见,那么它们之间必须有happens-before关系
-------:happens-before规则是具体阐释我们为了解决---本地内存带来的不可见性导致程序不正确执行问题-----的一些对内存模型的规定,而不是实现措施。
volatile内存语义:
把对volatile变量的读写看做使用锁对这个变量的读写操作进行同步操作来理解。
volatile怎么实现让变量的操作符合happens-before规则,先不说。
它在内存模型上起的作用:
-------1.对volatile变量的单个读/写具有原子性,但复合操作不具有原子性,比如i++
-------2.写一个volatile变量时,JMM会把该线程的本地内存的共享变量副本全刷到主内存中,
其它线程本地内存的副本失效(对每一个其它线程来说每个写对应一次失效,而不是对应多次失效),在读这个变量时,必须到主内存中读。
--------意味着,本地内存中,volatile变量以及其它变量都会刷新到主存中。
-------3.读一个volatile变量时,JMM会把该线程对应的本地内存置为无效。线程接下来从主存中读取共享变量
--------意味着,本地内存所有数据都失效了,要从主存中读取所有数据。
--------猜测只有在写后读,才会导致重读,如果读前无写,或者写读读的第二个读都不会导致重读(因为网上看的嗅探技术)
感觉不是很重要,先放一放
volatile导致重排序限制
前提理解:
------重排序;编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。
------单线程中数据依赖不会重排序,多线程中的数据依赖可能会
------控制依赖会被重排序
为了实现volatile的happens-before规则,JMM会限制编译器和处理器对操作进行重排序,