• volatile修饰数组


    结论:volatile修饰对象或数组时,只能保证他们的引用地址的可见性。

    非volatile数组的可见性问题

    public class Test {
        static int[] a = new int[]{1};
    
        public static void main(String[] args) {
            new Thread(() -> {  //线程A
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                a[0] = 0;
            }).start();
    
            new Thread(()-> {   //线程B
                try {
                    while (true) {
                        if (a[0] == 0) {
                            System.out.println("结束");
                            break;
                        }
                        //Thread.sleep(10);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    由此可见打印不出来‘’结束‘’
    在这里插入图片描述
    volatile数组的可见性问题

    public class Test {
        static volatile int[] a = new int[]{1};
    
        public static void main(String[] args) {
            new Thread(() -> {  //线程A
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                a[0] = 0;
            }).start();
    
            new Thread(()-> {   //线程B
                try {
                    while (true) {
                        if (a[0] == 0) {
                            System.out.println("结束");
                            break;
                        }
                        //Thread.sleep(10);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    在这里插入图片描述
    发现结果和我们预期的相反
    当ThreadB读取array时,因为array的引用被volatile修饰,所以ThreadB对所有变量都会从主内存去获取,当然也就包括array[0]。
    在这里插入图片描述
    https://stackoverflow.com/questions/53753792/java-volatile-array-my-test-results-do-not-match-the-expectations

    其实如果不给数组加volatile就永远不会打印“结束”,这种绝对的认为是错误的,volatile保证了其变量及时可见性而不会引起线程安全的问题,就算不加volatile,cpu在空闲的时候也会将array[0]的值从线程缓存刷新到主存,只是while(true)太快了,导致cpu一直没空。我们可以使用Thread.sleep(10)让出CPU让其有空将线程变量刷新到主内存中去。记得先去掉volatile修饰

    public class Test {
        static  int[] a = new int[]{1};
    
        public static void main(String[] args) {
            new Thread(() -> {  //线程A
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                a[0] = 0;
            }).start();
    
            new Thread(()-> {   //线程B
                try {
                    while (true) {
                        if (a[0] == 0) {
                            System.out.println("结束");
                            break;
                        }
                        Thread.sleep(10);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
  • 相关阅读:
    Spring简单例子引入Spring要点
    Open3D 隐藏点移除
    一个28岁程序员入行自述和感受
    力扣之滑动窗口《循序渐进》(209.长度最小的子数组、904. 水果成篮)
    MySQL数据库表空间回收问题
    2022蓝帽杯初赛wp
    数据库-多表设计
    基于单片机雨天自动关窗器的设计
    webGL编程指南 第三章 矩阵平移三角形.translatedTriangle_Matrix
    分享微信使用技巧,快来涨姿势啦
  • 原文地址:https://blog.csdn.net/qq_46548855/article/details/133428931