美文网首页
volatile的原理和使用

volatile的原理和使用

作者: junchang | 来源:发表于2019-02-21 23:31 被阅读0次

1.对线程的可见性

Java的volatile关键字声明使变量对不同线程具有可见性。程序在多线程操作non-volatile变量时,为了提升性能,每个线程会将变量从主内存复制到CPU缓存。如果有多个CPU核心,每个线程可能在不同的CPU上运行。这意味着每个线程的CPU缓存的变量的值可能不一样。如图所示:

import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

public class VolatileTest {
    private static Logger logger = Logger.getLogger(VolatileTest.class.getName());
    private static volatile int Counter = 0;

    public static void main(String[] args) {
        new ChangeListener().start();
        new ChangeMaker().start();
    }

    static class ChangeListener extends Thread {
        @Override
        public void run() {
            int localValue = Counter;
            while (localValue < 2) {
                //不加volatile Counter永远等于0,加volatile之后Counter会发生变化
                if (localValue != Counter) {
                    logger.info(Thread.currentThread().getName() + " 值被修改了 Counter = " + Counter);
                    localValue = Counter;
                }
            }
        }
    }

    static class ChangeMaker extends Thread {
        @Override
        public void run() {

            int localValue = Counter;
            while (Counter < 2) {
                logger.info(Thread.currentThread().getName() + " Counter+1 = " + (localValue + 1));
                Counter = ++localValue;
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

不加volatile 运行结果:

二月 22, 2019 12:06:56 上午 VolatileTest$ChangeMaker run
信息: Thread-2 Counter+1 = 1
二月 22, 2019 12:06:57 上午 VolatileTest$ChangeMaker run
信息: Thread-2 Counter+1 = 2

加了volatile 运行结果:

二月 22, 2019 12:05:30 上午 VolatileTest$ChangeMaker run
信息: Thread-2 Counter+1 = 1
二月 22, 2019 12:05:30 上午 VolatileTest$ChangeListener run
信息: Thread-1 值被修改了 Counter = 1
二月 22, 2019 12:05:31 上午 VolatileTest$ChangeMaker run
信息: Thread-2 Counter+1 = 2
二月 22, 2019 12:05:31 上午 VolatileTest$ChangeListener run
信息: Thread-1 值被修改了 Counter = 2

2.对线程的有序性

volatile可以禁止指令重排序,volatile标识的变量,会有内存屏障,指令重排序时就不能把后面的指令重排序到内存屏障之前的位置,这样就保证不同的代码块只能串行执行,不能同步执行,这样就保证了线程的有序性。

相关文章

网友评论

      本文标题:volatile的原理和使用

      本文链接:https://www.haomeiwen.com/subject/onfjyqtx.html