1.主要作用:用在多线程编程时,当在jvm开启优化性能的时候,强制线程在使用volidate修饰的变量的时候,从主内存中读取,不从线程副本内存中读取变量,从而保证了变量的同步安全。
2.为什么会有线程副本?
因为这个是jvm开启优化的一种方式。跟jvm内存分配有关。
简要分析:
有一个主内存,和运行线程复制主内存副本的内存。
当一个线程运行的时候,会把用的变量从主内存中读取到自己线程内存,在线程运行过程中操作变更的值都在本地内存存储,最后,再把线程内存中的值回写到主内存中。
这样,当别的线程运行时,也是从主内存中加载变量(其他线程还未写回写主内存),就会造成线程拿到的数据不是最新的,出现数据混乱。
当用volidate修饰变量的时候,就会强制所有线程每次读取变量,都从主内存中读取,并且变化直接操作主内存,不在本地线程内存。
但是用volidate修饰,并不能保证变量操作的原子性,即不能保证一个线程执行该变量时的原子操作,会被其他线程中断,引起数据不一致。
volidate是多线程环境下,可以保证不同的线程之间,操作同一个变量能互相通讯可见的。但是不能保证操作原子性。
volidate是如何保证内存可见性的/有序性,防止指令重排序?
主要是内存屏障,通过添加指令保证
可见性
1.通过指令。lock前缀指令。在由volidate修饰的变量,前后会加上lo