江明涛的博客
volatile关键字的内存可见性如何实现?
volatile关键字的内存可见性如何实现?

volatile关键字的内存可见性如何实现?

volatile关键字是Java中用来修饰变量的,它的作用是保证变量在多线程环境下的内存可见性。内存可见性指的是当一个线程修改了一个被volatile修饰的变量的值,其他线程能够立即看到这个修改,而不是使用自己线程私有的副本。

要理解volatile关键字的内存可见性实现,需要先了解Java内存模型(Java Memory Model,JMM)。JMM定义了Java线程如何和内存交互,以及在何时对共享变量的读写进行同步。

在JMM中,每个线程都有一个本地内存(local memory),线程对变量的操作都在本地内存中进行。而主内存(main memory)是所有线程共享的,它存储了所有的共享变量。

当一个线程读取一个共享变量时,会先从主内存中把这个变量的值读取到线程的本地内存中。当一个线程写入一个共享变量时,会先把这个值写入线程的本地内存,然后再刷新到主内存中。

如果一个共享变量被volatile修饰,那么它的读写操作就具有了特殊的语义,保证了内存可见性。

内存可见性的实现原理

1. 禁止重排序

为了保证内存可见性,JMM禁止编译器和处理器在volatile写操作之前和之后进行重排序。这意味着volatile写操作之前的所有操作都必须在volatile写操作完成之前完成,volatile写操作之后的所有操作都必须在volatile写操作完成之后才能执行。

2. 强制刷新缓存

为了保证内存可见性,JMM在写volatile变量时会强制将线程的本地内存中的变量值刷新到主内存中,将其他线程的本地内存中的变量值置为无效。这样其他线程在读取volatile变量时,就会从主内存中重新读取最新的值。

3. 无法保证原子性

volatile关键字能够保证内存可见性,但不能保证原子性。如果多个线程同时对volatile变量进行写操作,最终结果可能是不确定的。要保证原子性,可以使用其他的同步机制,比如synchronized关键字或者Lock。

总结

volatile关键字通过禁止重排序、强制刷新缓存的方式,实现了多线程环境下变量的内存可见性。它保证了当一个线程修改了一个volatile变量的值后,其他线程能够立即看到这个修改。

然而,需要注意的是,volatile关键字不能保证原子性。

上次更新时间 7 7 月, 2023 at 10:00 上午