volatile修饰数组或引用对象的问题

2019-07-10  本文已影响0人  slowwalkerlcr
    public static int[] array = new int[10];
    public static void main(String[] args) {
        new Thread(() -> {  //线程A
            try {
                TimeUnit.MILLISECONDS.sleep(100);
                array[0] = 2;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }).start();
        new Thread(()->{   //线程B
            try {
                while (true) {
                    if (array[0] == 2) {
                        System.out.println("结束");
                        break;
                    }
                    //Thread.sleep(10);
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }

2、当加上volatile修饰array时,WTF。。。“结束”打印出来了,这说明线程A修改array[0] = 2对线程B可见呢?这和我们开始得到的观点矛盾了(volatile只对数组的引用保证可见性,这里只修改了array的元素)

 public static volatile int[] array = new int[10];
    public static void main(String[] args) {
        new Thread(() -> {  //线程A
            try {
                TimeUnit.MILLISECONDS.sleep(100);
                array[0] = 2;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }).start();
        new Thread(()->{   //线程B
            try {
                while (true) {
                    if (array[0] == 2) {
                        System.out.println("结束");
                        break;
                    }
                    //Thread.sleep(10);
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }
 public static int[] array = new int[10];
    public static void main(String[] args) {
        new Thread(() -> {  //线程A
            try {
                TimeUnit.MILLISECONDS.sleep(100);
                array[0] = 2;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }).start();
        new Thread(()->{   //线程B
            try {
                while (true) {
                    if (array[0] == 2) {
                        System.out.println("结束");
                        break;
                    }
                    Thread.sleep(10);
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }

我们发现“结束”在没有volatile修饰的时候,一样有办法可以打印出来

image.png
上一篇下一篇

猜你喜欢

热点阅读