"深入理解Volatile关键字及可见性"

需积分: 10 1 下载量 141 浏览量 更新于2023-12-22 收藏 467KB PDF 举报
Volatile是Java中的一个关键字,它与多线程编程中的可见性和原子性相关。在多线程编程中,线程可以直接从主内存中读取变量的值,也可以将修改后的值立即写回主内存,然而在实际操作中,线程的本地缓存和主内存之间存在一定的延迟,导致一个线程对共享变量的修改对其他线程不可见。Volatile关键字可以确保在多线程环境中共享变量的可见性,保证线程能够及时的获取最新的变量值。 初步认识Volatile,可以从硬件层面了解可见性的本质。在多核处理器中,不同的核心拥有各自的本地缓存,线程可以在各自的本地缓存中读写变量,这导致共享变量的值在不同核心中可能不一致。Volatile通过强制线程在读写共享变量时直接操作主内存,从而保证了变量的可见性。 另外,了解Java内存模型(JMM)和HappenBefore的概念也有助于理解Volatile。JMM定义了Java程序中的线程如何和内存交互,保证了线程之间对共享变量的可见性和有序性。而HappenBefore是JMM中的一个概念,指定了两个操作之间的执行顺序,从而保证了有序性。 下面这段代码演示了一个使用Volatile和没有使用Volatile这个关键字的区别对于变量更新的影响: ```java public class VolatileDemo { public /*volatile*/ static boolean stop=false; public static void main(String[] args) throws InterruptedException { Thread thread=new Thread(()->{ int i=0; while(!stop){ i++; } }); thread.start(); System.out.println("begin start thread"); Thread.sleep(1000); stop=true; } } ``` 在这段代码中,我们定义了一个静态的布尔类型变量stop,并且使用Volatile关键字进行了标记。接着创建了一个线程,并在其中执行一个循环,直到stop变为true才退出循环。在主线程中,我们将stop设置为true,从而期望子线程可以及时地检测到变量的更新并退出循环。然而,由于子线程的本地缓存可能并没有及时更新,导致子线程无法获取到最新的stop的值,进而陷入了死循环。 如果将Volatile关键字去掉,那么主线程对stop的修改对子线程是不可见的。这是因为线程在执行过程中会将变量的值拷贝到线程的本地内存中进行操作,不会立即写回主内存。而使用Volatile关键字,可以保证线程在读写共享变量时直接操作主内存,从而解决了变量可见性的问题。 在实际的程序开发中,我们需要注意使用Volatile关键字以及合理地设计多线程程序,保证变量的可见性和有序性,避免出现类似并发问题。通过初步认识Volatile以及从硬件层面了解可见性的本质,我们能更好地理解多线程编程中的相关概念,提高程序的健壮性和可靠性。