Java内存模型
java中,实例变量、静态变量、数组,都是分配到主内存的。各个线程都有自己独立的内存空间,通常是处理器缓存或者寄存器空间,线程之间是不能访问彼此的独立内存空间的。
线程之间是共享主内存空间的,线程内存都有独立的栈,用于存储局部变量。
假如某个进程开启了两个线程,分别在不同的处理器上执行。
此时,线程1操作了Object1对象,并更新的它的值,但是没有同步到主内存中,此时线程2读取到Object1对象的值是更新前的旧值么?
假如,线程1操作了Object1对象,并更新的它的值,并同步到主内存中,此时线程2读取到Object1对象的值是更新后的新值么,会不会有脏数据?
内存操作的原子性
JMM规范了long和double类型之外的对象的读和写的原子性。后续会了解到,long和double类型标记为volatile则读写操作也是原子的。
内存操作的可见性
JMM规范了单个线程操作变量值后,其他线程看到变量值改变的时机问题。
1. 当某个线程初次读取某个变量值的时候,他读到的是变量的默认值,或者其他线程已经写入的值。
2. 当读、写volatile变量的时候,操作的是主内存的值,不是线程自己的存储空间的值,因此当写入volatile的变量的时候,其他线程看到的是最新的值(立即可见)。
3. 当一个线程终止了,他的工作内存会被同步到主内存中,原来仅自己可见的值会被其他线程看到。
4. 线程进入同步代码块,会从工作内存中重新加载最新的值,退出同步代码块的时候,会将工作内存中的数据同步到主内存。
内存操作的排序
JMM规定了,单个线程内部的代码执行逻辑是有序的。多个线程之间的执行顺序是不能保证的。当然,可以使用同步策略来实现不同线程之间的代码的排序问题。