015 可见性问题与volatile

一 . 概述

可见性问题:

  什么是可见性问题?可见性问题的原因是什么?

  可见性问题完全是JVM的结构造成的,JVM为了高速的运行,对每一个线程进行了线程栈的设计,在线程栈之中设置了高速的缓存.

    缓存之中存在共享变量的副本,在有些时候,因为来不及维护副本和实体的一致性可能造成问题,这种问题就是可见性问题.

注意: 当我们解决的原子性的同时也就完成了可见性的问题的解决.


二 . 可见性性问题的例子:

public class VisiableProblem extends Thread {
    private  boolean isRunning = true;

    public boolean isRunning() {
        return isRunning;
    }

    public void setRunning(boolean isRunning) {
        this.isRunning = isRunning;
    }

    public void run() {
        System.out.println("进入了run...............");
        while (isRunning) {
        }
        System.out.println("isUpdated的值被修改为为false,线程将被停止了");
    }

    public static void main(String[] args) throws InterruptedException {
        VisiableProblem volatileThread = new VisiableProblem();
        volatileThread.start();
        Thread.sleep(1000);
        volatileThread.setRunning(false); // 停止线程
    }
}

我们希望主线程可以同步标记位停止子线程,但是很让人失望,子线程无法终止.

  原因就是子线程使用了副本的内容,这个副本永远是true的.


三 . 使用volatile解决可见性

  我们只要在

private  volatile boolean isRunning = true;

增加一个volatile就能解决这个问题.

  volatile的关键词的作用:

    [1]保证副本和主存之间的一致性

    [2]打破指令重排序(这个在后面会说一下)

  当我们看到了volatile的作用之后就知道怎么为什么能解决上述的问题了.


四 .分析

volatile可以解决可见性问题,但是无法解决原子性.

  而线程的安全性问题的解决需要的是原子性而不是可见性,也就是说可见性是原子性的一个保证,但无法保证原子性.

  这也就决定了我们不能依靠volatile来实现同步.

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