1 . 保证了不同线程对该变量操作的内存可见性;
2 . 禁止指令重排序
volatile不适合复合操作
volatile具有可见性、有序性,不具备原子性。
在Java中,基本类型的变量的读取和赋值操作是原子性操作
原子性
基本类型的读取和赋值操作,且赋值必须是数字赋值给变量,变量之间的相互赋值不是原子性操作。
java.concurrent.Atomic.* 包中所有类的一切操作
可见性
指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
有序性
程序执行的顺序按照代码的先后顺序执行。
最著名的例子就是单例模式里面的DCL(双重检查锁)。
// volatile关键字会强制的保证线程的可见性
private static boolean flag = true;
private static void setI(boolean state) {
System.out.println("线程设置了stop begin");
flag = state; // 赋值 可见性测试,是否会使用高速缓存中的变量
System.out.println("线程设置了stop end");
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
System.out.println("进入方法" + flag);
while (flag) {
//System.out.println("方法执行");
/**JVM会尽力保证内存的可见性 导致CPU的输出 耗时,CPU就有可能有时间去保证内存的可见性
* public void println(String x) {
* synchronized (this) {
* print(x);
* newLine();
* }
* }
*/
}
System.out.println("线程结束");
});
t1.start();
Thread.sleep(1000);
setI(false);
}
volatile 的区别,不加 线程一直存活,修改后的参数!未被读取。
加volatile 线程立刻停止,强制刷新主内存