Java 并发面试题, Java 中 volatile 关键字的作用是什么?
Java 并发面试题, Java 中 volatile 关键字的作用是什么?
QA
Step 1
Q:: Java 中 volatile 关键字的作用是什么?
A:: volatile 关键字用于指示 Java 虚拟机(JVM)一个变量的值可能会被多个线程同时修改和读取。使用 volatile 关键字声明的变量会有以下两个效果:1. 保证变量的可见性:当一个线程修改了 volatile 变量的值,其他线程会立即看到这个修改。2.
禁止指令重排序优化:volatile 变量在读取和写入时会通过内存屏障来禁止指令重排序,以保证变量的线程可见性和有序性。
Step 2
Q:: volatile 关键字的使用场景有哪些?
A:: volatile 关键字适用于以下场景:1. 状态标志变量:用于表示程序运行状态的标志变量,如停止标志。2. 单例模式中的双重检查锁定:使用 volatile 关键字确保实例被正确地初始化。3.
配置项或统计数据的实时更新:当配置项或统计数据需要实时更新并被多个线程访问时,使用 volatile 关键字。
Step 3
Q:: volatile 和 synchronized 的区别是什么?
A:: volatile 关键字主要用于保证变量的可见性和禁止指令重排序,而 synchronized 关键字则用于保证代码块或方法的原子性和互斥性。volatile 不能用于保证复合操作的原子性,而 synchronized 能够做到。此外,synchronized 会引入线程阻塞和上下文切换的开销,而 volatile 不会。
Step 4
Q:: volatile 能保证操作的原子性吗?
A:: 不能。volatile 关键字只能保证变量的可见性和禁止指令重排序,但不能保证操作的原子性。如果需要保证操作的原子性,应该使用 synchronized 或者 Java 提供的原子类(如 AtomicInteger)。
Step 5
Q:: 什么是内存屏障(Memory Barrier)?
A:: 内存屏障是一种 CPU 指令,用于强制实现对内存操作的排序。它能确保在屏障之前的内存操作在屏障之后的操作之前完成,以此来避免指令重排序对程序正确性的影响。Java 中使用 volatile 关键字时,编译器会在读写 volatile 变量的地方插入内存屏障。