zoukankan      html  css  js  c++  java
  • Java并发编程之volatile关键字

    简介

    volatile关键字主要是用来解决共享变量内存可见性问题CPU指令乱序执行问题

    下面通过一个实例来说明下这两个问题导致的原因和volatile如何解决这两个问题。

    volatile的使用

    public class TaskRunner {
    
        private static int number;
        private static boolean ready;
    
        private static class Reader extends Thread {
    
            @Override
            public void run() {
                while (!ready) {
                    Thread.yield();
                }
    
                System.out.println(number);
            }
        }
    
        public static void main(String[] args) {
            new Reader().start();
            number = 42;
            ready = true;
        }
    }
    

    上面程序的执行结果除了延迟一段时间正常输出42之外,还可能存在以下两种结果:

    1.线程永远不会停止

    这种情况属于前面说的共享变量内存可见性问题。可见性是指当一个线程修改了某一个共享变量的值时,其他线程是否能够立即知道这个修改。

    如下Java内存模型的抽象图所示,线程之间的共享变量都存储在主内存中,但每个线程本地内存都会存有共享变量的副本。假设前面例子中主线程和子线程分别在不同的CPU里,主线程将ready的值设置为true,这个值并不会立刻同步到主内存,所以子线程也就不能读取到最新的值,而读取的是本地内存变量副本的值。

    2.线程结束,输出结果number值为0

    这种情况属于前面说的CPU指令乱序执行问题。CPU的速度至少比内存快100倍,为了提升效率,会打乱原来的执行顺序,会在一条指令执行过程中,去同时执行另一条指令,当然乱序执行的前提是两条指令没有依赖关系

    在单线程的情况下,重排序能够保证乱序执行结果和顺序执行结果是一致的,但是在多线程的情况下就可能会有问题了。如上可能会出现ready = true先执行,而number = 42则刚好在输出语句后执行。

    使用volatile避免出现上述问题
    public class TaskRunner {
    
        private volatile static int number;
        private volatile static boolean ready;
    
        //...
    }
    

    1.当一个变量被声明volatile时,线程对它的修改会直接刷新到主内存,其他线程对它的读取也是直接从主内存读取,这样就能保证所有线程读取到这个变量的值都是一致的。

    2.volatile能够禁止指令重排序,在被声明volatile变量上面执行的指令不可以乱序。

    volatile和synchronized的比较

    volatile是轻量级的synchronized,它能保证可见性和有序性,但它不能保证原子性。之所以说volatile是轻量级的synchronized,是因为volatile的执行效率要更高,而synchronized是独占锁,会有锁的开销。

    synchronized能够保证可见性,当线程进入synchronized块时,会先清空本地内存中的变量值,然后从主内存中读取最新的值。当线程退出synchronized块时,会将本地内存中的变量值同步到主内存。

    synchronized块可以看作一个整体,同一时间只有一个线程运行synchronized块代码,不会被其他线程干扰,所以也就能保证原子性和有序性。

  • 相关阅读:
    Study Plan The Twelfth Day
    Study Plan The Fifteenth Day
    Study Plan The Seventeenth Day
    Study Plan The Tenth Day
    Study Plan The Eighth Day
    Study Plan The Eleventh Day
    Study Plan The Sixteenth Day
    Study Plan The Thirteenth Day
    Study Plan The Fourteenth Day
    Study Plan The Ninth Day
  • 原文地址:https://www.cnblogs.com/seve/p/14520125.html
Copyright © 2011-2022 走看看