• 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来实现同步.

  • 相关阅读:
    C语言I博客作业05 sun
    C语言I博客作业08 sun
    C语言I博客作业02 sun
    C语言I博客作业04 sun
    elastix的web端口修改
    mysql.proc错误解决
    Client.Error.MessageSend 错误解决方案
    让secureCRT正确显示中文
    elastix的多个inbound route的设置
    PHP5.1时间相差8小时问题解决。
  • 原文地址:https://www.cnblogs.com/trekxu/p/8996318.html
Copyright © 2020-2023  润新知