zoukankan      html  css  js  c++  java
  • volatile--共享数据必须保证可见性

    在Effective Java中看到的,试了一下,有点意思,考查的知识点是volatile关键字。

    下面这段代码,预期是打印it takes xxxx miliseconds. 。但实际上,陷入了死循环。

     1 public class ThreadNeverStop {
     2     
     3     private static boolean stopRequested;
     4     
     5     public static void main(String[] args) throws InterruptedException {
     6         Thread backgroundThread = new Thread(new Runnable() {
     7             
     8             @Override
     9             public void run() {
    10                 long start = System.currentTimeMillis();
    11                 while (!stopRequested) {
    12                     //whatever
    13                 }
    14                 long end = System.currentTimeMillis();
    15                 System.out.println("it takes " + (end - start) + " miliseconds.");
    16             }
    17         });
    18         
    19         backgroundThread.start();
    20         
    21         Thread.sleep(1000L);
    22         
    23         stopRequested = true;
    24     }
    25 }

    学习过Java内存模型就会知道,这是因为stopRequested这个域,在主线程和backgroundThread中各有备份。当主线程执行完毕,将新值刷到主内存中,backgroundThread并没有从主内存获取最新的值,导致一直判断为false.

    最直接的方法是使用同步,但还有更简洁,轻量的方法,那就是使用volatile。volatile关键字修改的共享变量,线程在访问时,会向主内存获取最新的值。

    之前一直认为【如果不需要原子性,对于共享变量可以不用volatile,反正线程执行完一定会刷新到主内存】,忘记了可能另外的线程同时甚至更早已经获取了共享变量的值,没有继续从主内存中获取最新的值。为了确保共享变量修改后,可以知会到其他线程,并且其他线程在使用到共享变量时能够主动向主内存获取最新值,应该要使用volatile。

  • 相关阅读:
    OpenCV在MFC图像控件内显示图像
    Android APK反编译具体解释(附图)
    Android下用Properties保存程序配置
    王灏:光音网络致力打造Wi-Fi大生态圈
    解决ccSvcHst.exe CPU占用超50%的问题,及其缘由
    配置管理工具比較
    应用程序无法正常启动0xc0150002 解决方式
    现有一些开源ESB总线的比較
    使用GridView自带分页的代码
    Hadoop 2.4.0新特性介绍
  • 原文地址:https://www.cnblogs.com/kingsleylam/p/6081889.html
Copyright © 2011-2022 走看看