011 volatile关键词

一 .概述

  在前面,我们说到了volatile关键词可以保证可见性和有序性,本节,首先展示一个例子.

public class VolatileTest {

    private boolean flag = true;

    public static void main(String[] args) throws Exception {
        VolatileTest bean = new VolatileTest();
        new Thread(() -> {
            bean.run();
        }).start();

        TimeUnit.SECONDS.sleep(1);
        
        new Thread(() -> {
            bean.stop();
        }).start();
    }

    public void run() {
        for (;;)
            if (flag) {
            } else {
                return;
            }
    }

    public void stop() {
        this.flag = !flag;
    }
}

我们在上面的例子之中,创建两个线程,使用一个标记位来终结一个线程的执行,但是当我们运行的时候,我们发现我们根本就不能终结这个线程的执行,

  原因,在上面我们已经分析过了,就是可见性的问题.

  flag 这个变量的值的修改即使写入了主存,但是另一个线程使用的也还是那个副本,这样就出现了无线循环的效果.


二.问题的解决

  为了解决上面的问题,我们只需要在flag前面加上volatile关键词就能解决.

private volatile boolean flag = true;

当我们加入了这个关键词时候,一旦flag的状态发生了变化,JVM强制所有使用的线程进行数据同步,这样可见性的问题就解决了.


三 .有序性和happen-before原则

  在前面我们说到了使用volatile关键词还能解决有序性的问题,实际上这个有序性是很弱的一个有序性的解决方法.

  首先需要声明这样的一个原理:JVM定义了一个代码的关键点,在这些关键点之中,顺序永远不会错乱,我们将这些规则称为happen-before原则.

  我们需要解决的就是关键点之中的一些有序性的问题,一般情况下我们会依赖使用锁解决,但是某一些情况我们也可以使用voldatile关键词来实现.

引用thinking in java中的话,我们应该依赖锁机制而不是弱机制volatile.

原文地址:https://www.cnblogs.com/trekxu/p/9524010.html