时间记录:2020-2-1
上章节了解到了关于内存的一些操作和简单的规则,在其中volatile属于一个比较特殊的内容的操作,而也存在一些特殊的变量的内存操作的特殊性,long,double的操作的特殊性,但是其表现没有什么差异。
Volatile型变量的特殊规则
在java中volatile为一个关键字,是一种轻量级的同步机制,但是其在一些的特定场景下的操作比较合适,不是完全的同步,其只是对所有线程是可见的,其实际上的意义是线程在使用被其修饰的变量的时候一定是先从主内存中进行同步,然后再进行使用。
volatile的几个特性
1:被此修饰的变量对所有线程的可见性,这里的可见性是指当一条线程修改看这个变量的值,新值对于其他线程来说是可以立即得知的。(注意:这里的立即得知其实是对变量的使用定下了规则,必须从主内存中进行获取)
2:被此修饰的变量在发生改变的时候得马上返回到主内存,也就是进行同步的操作
3:禁止指令排序优化(这个在jdk1.5中才完全被修复,关于被修饰的禁止指令排序优化)
指令重排序 是指cpu采用了允许将多条指令不安程序规定的顺序分开发送个各相应电路单元出路(这里应该是指集成的寄存器,个人猜测)
常见的误解
【volatile变量对所有线程是立即可见的,对volatile变量所有的写操作都能立刻反应到其它线程之中,换句话说,volatile变量在各个线程中是一致的,所以基于volatile变量的运算在并发下是安全的】
在各个线程的工作内存中,volatile变量可以存在不一致的情况,但是由于每次使用之前都要进行刷新,执行引擎看不到不一致的情况,因此可以认为不存在一致性问题,但是java里面的运算并不是一致性的,导致了volatil变量在并发下一样是不安全的。
package com.huo.mem;
public class VolatileTest
{
public static volatile int race = 0;
public static void increase() {
race ++;
}
private static final int THREAD_COUNT = 20;
public static void main(String[] args)
{
Thread[] threads = new Thread[THREAD_COUNT];
for