JMM是Java内存模型,与JVM内存模型是两回事。 JMM的主要目标是定义程序中变量的访问规则(Happens-Before )。 在底层处理器内存模型的基础之上,定义自己的多线程。
JMM规定: 要想保证B操作能够看到A操作的结果(无论它们是否在同一个线程),那么A和B之间必须满足Happens-Before 关系.
- 所有的变量都存储在主内存中----->共享。
- 每条线程还有自己的工作内存(相当于高速缓存,有利于提高访问速度)。
- 工作内存中保存的是主内存中变量的副本(copy),线程对变量的读写操作是在自己的工作内存中进行,而不是直接读写主内存中的变量。
不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。
Java内存模型的三大特性:原子性、可见性、有序性
多线程进行数据操作时,将可能发生线程安全问题,因此JMM需要提供原子性、可见性、有序性的保证。
volatile关键字
volatile关键字的特性是Java内存模型规定的 1.保证被此关键字修饰的变量对所有线程的可见性 2.禁止指令重排序 编译器重排序–>JVM重排序–>内存重排序
内存间(主内存和工作内存)的交互操作
变量从主内存读取到工作内存,然后同步回工作内存的细节,这就是主内存与工作内存之间的交互协议。 Java内存模型定义了以下8种操作来完成,它们都是原子操作(除了对long和double类型的变量)。
作用主内存:
- lock(锁定)
作用于主内存中的变量,它将一个变量标志为一个线程独占的状态。 - unlock(解锁)
作用于主内存中的变量,解除变量的锁定状态,被解除锁定状态的变量才能被其他线程锁定。 - read(读取)
作用于主内存中的变量,它把一个变量的值从主内存中传递到工作内存,以便进行下一步的load操作。 - write(写入)
作用于主内存中的变量,它把store传递过来的值放到主内存的变量中。
作用工作内存:
- load(载入)
作用于工作内存中的变量,它把read操作传递来的变量值放到工作内存中的变量副本中。 - use(使用)
作用于工作内存中的变量,这个操作把变量副本中的值传递给执行引擎。当执行需要使用到变量值的字节码指令的时候就会执行这个操作。 - assign(赋值)
作用于工作内存中的变量,接收执行引擎传递过来的值,将其赋给工作内存中的变量。当执行赋值的字节码指令的时候就会执行这个操作。 - store(存储)
作用于工作内存中的变量,它把工作内存中的值传递到主内存中来,以便进行下一步write操作。
在将变量从主内存读取到工作内存中,必须顺序执行read、load。读取载入 要将变量从工作内存同步回主内存中,必须顺序执行store、write。存储写入
|