从0到1理解JVM_内存模型

JAVA 支持并发线程操作,其内存模型也不是简单的所有线程共同操作内存。在 JVM 中,每个线程都有自己的内存空间,线程的操作都在自己的内存空间中执行,必要时再同步到公共内存,让其它的线程看见。

volatile

volatile 关键字保证了各个线程都能实时性地看到某个变量的值,它是怎么做到的呢?

被 volatile 修饰的变量具有特殊性,欲更改该变量的值的线程必须先从公共内存中获取该变量的值,存入自己的空间进行操作,改完了还必须“立刻”同步回公共内存,以便其它线程知道变量值被改变,这维护了变量的一致性。

volatiel 还能保证指令不会被“重排序”,volatile 修饰了哪个变量,该变量的赋值等操作的次序就不能被编译器优化。

但 volatile 并不能保证原子性。虽然各个线程都能看到变量值的变化,但有可能有两个线程都修改该变量的值,其中任何一个线程的操作都有可能不是原子操作。

原子性

原子性有 synchronized 来保证,被 synchronized 修饰的方法,在一段时间内只能由一个线程执行。

可见性

可见性是指,一个变量的值被一个线程改变后,其它线程能够立即知晓,而不会导致彼此线程间不知道对方做了什么。
该性质明显可以由 volatile 来保证,另外,synchronized也能保证可见性,为什么呢?

被 synchronized 修饰的变量在被一个线程修改时,别的线程不能碰该变量,当轮到别的线程时,别的线程自然就看到变量被前一个线程修改了。

有序性

volatile 和 synchronized 都能保证有序性。

volatile 阻止指令的重排序优化,而 synchronized 使得线程们只能一个个排着队来执行某段代码。