Java多线程之信用盘搭建出租volatile关键字和内存屏障

volatile是JVM提供的一种最轻量级的同步机制,信用盘搭建出租Q【1152880099】因为Java内存模型为volatile定义特殊的访问规则,使其可以实现Java内存模型中的两大特性:可见性和有序性。正因为volatile关键字具有这两大特性,所以我们可以使用volatile关键字解决多线程中的某些同步问题。

1、volatile的可见性
volatile的可见性是指当一个变量被volatile修饰后,这个变量就对所有线程均可见。白话点就是说当一个线程修改了一个volatile修饰的变量后,其他线程可以立刻得知这个变量的修改,拿到最这个变量最新的值。

结合前一篇文章提到的Java内存模型中线程、工作内存、主内存的交互关系,我们对volatile的可见性也可以这么理解,定义为volatile修饰的变量,在线程对其进行写入操作时不会把值缓存在工作内存中,而是直接把修改后的值刷新回写到主内存,而当处理器监控到其他线程中该变量在主内存中的内存地址发生变化时,会让这些线程重新到主内存中拷贝这个变量的最新值到工作内存中,而不是继续使用工作内存中旧的缓存。

下面我列举一个利用volatile可见性解决多线程并发安全的示例:

public class VolatileDemo { //private static boolean isReady = false; private static volatile boolean isReady = false; static class ReadyThread extends Thread { public void run() { while (!isReady) { } System.out.println("ReadyThread finish"); } } public static void main(String[] args) throws InterruptedException { new ReadyThread().start(); Thread.sleep(1000);//sleep 1秒钟确保ReadyThread线程已经开始执行 isReady = true; } }
上面这段代码运行之后最终会在控制台打印出:ReadyThread finish,而当你将变量isReady的volatile修饰符去掉之后再运行则会发现程序一直运行而不结束,而控制台也没有任何打印输出。

我们分析下这个程序:初始时isReady为false,所以ReadyThread线程启动开始执行后,它的while代码块因标志位isReady为false会进入死循环,当用volatile关键字修饰isReady时,main方法所在的线程将isReady修改为true之后,ReadyThread线程会立刻得知并获取这个最新的isReady值,紧接着while循环就会结束循环,所以最后打印出了相关文字。而当未用volatile修饰时,main方法所在的线程虽然修改了isReady变量,但ReadyThread线程并不知道这个修改,所以使用的还是之前的旧值,因此会一直死循环执行while语句。

猜你喜欢

转载自www.cnblogs.com/xihuankan/p/11027017.html