电脑:内存 L1 L2 L3 缓存 CPU ctrl+atl+del就可以看到
Java 有线程内存,在执行线程的时候,会从主内存把变量加载到工作内存(缓存),所以,在多线程同时改变一个静态变量时候,实际是分开相互不影响的
下面是程序例子
以下是运算结果
从此可以看出,第一个线程并没有退出,initFlag因为在第一个线程没有变成false,因为是工作内存
如果想让第一个内存的变量改变,加一个修饰 volatile
工作原理
在没有加volatile 时候,线程1没有store和write回主内存动作有,也没有重新读的过程,所以线程1一直在那空转,也没有改变。
volatile早期的解决方式,就是单例模式,有且只有一个线程可以访问到这个主内存的变量
MESI缓存原理 通过嗅探机制 发现主内存在总线里变了,就重新读取
查看 Java的汇编代码除了运行程序加以上的参数之外,还要下载工具到jre的bin下(hsdis-amd64)
结合配合以volatile的读/写和CAS所具有的volatile读和写的内存 ,AQS,非阻塞数据结构和原子变量类(java.util.concurrent.atomic包中的类
上例子:
不保证原则性
t.join()是等待threads所有的线程都执行完,再去往下执行System.out.println(num);
第一次结果
第二次结果
因为volatile没办法保证原子性,在往主内存写的时候,可能多个线程同时写会一个值
线程1回写主内存后,线程2失效了,又重新读主内存到工作内存,值和线程1的一样,然后把工作内存写回主内存,就原来正常先后顺序是12,结果同时情况下就变成11
有序性
运行一下
运行结果是:四种组合结果都有可能 因为CPU会将指令重排序
所以 解决的方法就是在代码前加volatile
也就是,加了volatile的代码,CPU不会重排序把他前面那行代码放它后面去执行
后续需要继续学习的知识内容