可见性问题小案例

来源:互联网 发布:微信公众平台配置域名 编辑:程序博客网 时间:2024/05/16 14:55
package com.shihou.module.task.controller;/** * 可见性问题测试 * Created by Administrator on 2017/5/10. */public class VisibilityTest {    private static boolean ready;    private static int number;    private static class ReaderThread extends Thread{        public void run() {            try {                Thread.sleep(10);            } catch (InterruptedException e) {                e.printStackTrace();            }            if (!ready) {                System.out.println(ready);            }            System.out.println(number);        }    }    private static class WriterThread extends Thread {        public void run() {            try {                Thread.sleep(10);            } catch (InterruptedException e) {                e.printStackTrace();            }            number = 100;            ready = true;        }    }    public static void main(String[] args) {        new WriterThread().start();        new ReaderThread().start();    }

}

结果:

这个结果也只能说是有可能是可见性造成的,当写线程(WriterThread)设置ready=true后,读线程(ReaderThread)看不到修改后的结果,所以会打印false,对于第二个结果,也就是执行if (!ready)时还没有读取到写线程的结果,但执行System.out.println(ready)时读取到了写线程执行的结果。不过,这个结果也有可能是线程的交替执行所造成的。Java 中可通过Synchronized或Volatile来保证可见性

解释:

从这个图中我们可以看出,每个线程都有一个自己的工作内存(相当于CPU高级缓冲区,这么做的目的还是在于进一步缩小存储系统与CPU之间速度的差异,提高性能),对于共享变量,线程每次读取的是工作内存中共享变量的副本,写入的时候也直接修改工作内存中副本的值,然后在某个时间点上再将工作内存与主内存中的值进行同步。这样导致的问题是,如果线程1对某个变量进行了修改,线程2却有可能看不到线程1对共享变量所做的修改。

0 0
原创粉丝点击