绪论:并发的核心特性
2023-12-10 03:20:47
浅谈 JMM 与并发三大特性(volatile、MESI、内存屏障)
在计算机科学领域,并行与并发一直是绕不开的话题。并行处理基于多处理器或多核系统,利用其多个处理单元同时执行多个任务,提高计算效率。而并发则关注于处理多线程或多进程,使不同任务能在同一时间段内交替执行,增强系统的响应能力。
并发处理过程中,对内存访问的同步至关重要。为了确保不同线程或进程对共享内存的访问不会产生冲突,Java 虚拟机(JVM)引入了 JMM(Java 内存模型)规范和一系列并发特性,确保程序的正确性和一致性。
JMM:内存访问的统一规范
JMM 规定了一组规则,指导 Java 程序中不同线程或进程对共享内存的访问。它定义了内存可见性、有序性以及原子性等关键概念,确保不同线程操作内存时的预期行为和结果。
Volatile:强制内存可见性
Volatile 被用来修饰变量,确保该变量的修改能立即对所有线程可见。它通过禁止对 Volatile 变量的读写操作进行重排序,强制系统在每次读写时都直接访问主内存,保证不同线程看到该变量的最新值。
MESI:缓存一致性协议
MESI(Modified、Exclusive、Shared、Invalid)协议是一种缓存一致性协议,用于解决多处理器系统中不同缓存之间的同步问题。它通过维护缓存块的状态(已修改、独占、共享、无效),保证不同处理器访问内存时得到一致的数据。
内存屏障:控制指令重排序
内存屏障是一种特殊的指令,用于控制指令的执行顺序。它可以阻止编译器或处理器对指令进行重排序,确保某些指令在其他指令执行之前或之后执行,从而保证内存访问的顺序性。
案例分析:volatile 的应用
为了更好地理解 Volatile 的作用,让我们看一个简单的示例:
public class VolatileTest {
private volatile int counter = 0;
public void incrementCounter() {
counter++;
}
public int getCounter() {
return counter;
}
}
在多线程环境中,如果没有 Volatile 关键字修饰 counter 变量,编译器或处理器可能会对指令进行重排序,导致 counter 值的修改对其他线程不可见。而使用 Volatile 后,系统将强制在每次对 counter 进行修改时都直接访问主内存,确保不同线程始终能看到 counter 的最新值。
结论
JMM、Volatile、MESI 和内存屏障是并发编程中必不可少的特性,它们共同保障了多线程或多进程环境下内存访问的正确性和一致性。理解这些特性对于编写可靠、高效的并发程序至关重要。