Java并发面试题, 什么是 Java 中的原子性,可见性和有序性?
Java并发面试题, 什么是 Java 中的原子性,可见性和有序性?
QA
Step 1
Q:: 什么是 Java 中的原子性?
A:: Java 中的原子性(Atomicity)指的是一个操作或一系列操作要么全部执行,要么全部不执行,无法被中途打断。原子性是并发编程中的一个重要概念,用于确保在多线程环境下共享变量的安全访问。Java 中的 synchronized
关键字、java.util.concurrent.atomic
包中的类(如 AtomicInteger
,AtomicBoolean
)以及数据库事务等都提供了原子性保障。
Step 2
Q:: 什么是 Java 中的可见性?
A:: Java 中的可见性(Visibility)指的是当一个线程修改了共享变量的值后,其他线程能立即看到这个修改。可见性问题是由于 CPU 缓存导致的,多个线程可能在各自的缓存中保留了共享变量的副本,导致数据不同步。Java 中通过 volatile
关键字、synchronized
关键字和显式的锁(如 ReentrantLock
)来保证可见性。
Step 3
Q:: 什么是 Java 中的有序性?
A:: Java 中的有序性(Ordering)指的是程序执行时的顺序保证。在多线程环境中,代码的执行顺序可能会由于编译器优化、CPU 重排序和内存模型等原因发生变化,导致线程间的指令执行顺序无法预测。Java 通过 synchronized
关键字和 volatile
关键字保证了一些有序性。Java 内存模型(Java Memory Model,
JMM)定义了哪些操作可以重排序,哪些操作不能。
Step 4
Q:: 如何通过代码示例解释 Java 中的原子性?
A:: 可以通过一个银行转账的例子来解释原子性问题。假设有两个线程同时从同一个账户转账,由于转账操作不是原子的,可能会导致余额计算错误。使用 synchronized
或 AtomicInteger
可以保证转账操作的原子性,避免此类问题。
Step 5
Q:: 什么是 Java 内存模型(Java Memory Model,
JMM)?
A:: Java 内存模型是 Java 虚拟机规范的一部分,它定义了在并发环境下,线程对变量的读取和写入行为。JMM 规定了如何在多线程之间传递变量的值,以及在何种情况下可以重排序指令。JMM 的核心概念是原子性、可见性和有序性,理解 JMM 有助于编写正确的并发程序。
Step 6
Q:: 什么是 volatile
关键字?它如何影响可见性和有序性?
A:: volatile
是 Java 中的一个修饰符,用于标记变量,使其具有可见性和有序性保障。当一个变量被声明为 volatile
,对该变量的读写操作不会被线程缓存,每次操作都直接从主内存中读取或写入。这保证了线程对该变量的最新修改是可见的。此外,volatile
还禁止指令重排序,从而保证有序性。