Java之volatile修饰数组的简介及示例说明

戚薇 Java教程 发布时间:2023-07-03 09:39:07 阅读数:14669 1
下文笔者讲述volatile修饰数组的简介及示例说明
学习完本篇之后,你将彻底掌握volatile修饰数组的相关操作说明,如下所示
volatile关键字可修饰数组
  但是他只是修饰数组的引用信息,而不是整个数组
  当修改数组的引用时,此时会收到volatile保护
  当修改数组中的元素,则volatile不会起到保护作用

volatitle关键字的简介

volatile是Java中的关键字
  是Java虚拟机提供的轻量级的同步机制
volatile有三个特性:
  1.保证可见性
  2.不保证原子性
  3.禁止指令重排

未使用volatitle关键字

public class Demo {
 
    class Data {
        private int index = 0;
 
        public void setIndex(int index) {
            this.index = index;
        }
 
        public int getIndex() {
            return this.index;
        }
    }
 
    public Demo() {
        final Data data = new Data();
 
        // 在线程中修改数据
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    System.out.println("线程开始执行...");
                    data.setIndex(10);
                    System.out.println("线程执行结束");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
 
        while(data.getIndex() == 0) {
            // 如果进入这里,表示不可见
        }
 
        System.out.println("index 是可见的");
    }
 
    public static void main(String[] args) {
        new Demo();
    }
 
}

//运行以上代码,将输出以下信息

线程开始执行...
线程执行结束

//我们在线程中通过 setIndex() 方法
  将Data中的index设置为10
  主线程中的while循环也没有结束
  线程中的修改对主线程是不可见的
  此时,使用volatile 关键字去修饰 index 属性
  可让他可见
例:采用volatile修饰index变量
使其可见
public class Demo {
 
    class Data {
        private volatile int index = 0;
 
        public void setIndex(int index) {
            this.index = index;
        }
 
        public int getIndex() {
            return this.index;
        }
    }
 
    public Demo() {
        final Data data = new Data();
 
        // 在线程中修改数据
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    System.out.println("线程开始执行...");
                    data.setIndex(10);
                    System.out.println("线程执行结束");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
 
        while(data.getIndex() == 0) {
            // 如果进入这里,表示不可见
        }
 
        System.out.println("index 是可见的");
    }
 
    public static void main(String[] args) {
        new Demo();
    }
 
}

//运行以上代码,将输出以下信息
线程开始执行...
线程执行结束
index 是可见的

volatile修饰数组

例一:volatile 对数组整体引用效果

定义一个int数组
   使用volatile修饰
在while循环中一直比较数组的hashCode是否一致
   不一致则跳出循环
 
 当在线程中将变量 array 指向新的数组
   此时当前数组的 hashCode 和 历史数组的 hashCode 就不一致,跳出循环
public class Demo {
 
    class Data {
        private volatile int[] array = new int[10];
 
        public void setArray(int[] newArray) {
            this.array = newArray;
        }
 
        public int[] getArray() {
            return this.array;
        }
    }
 
    public Demo() {
        final Data data = new Data();
        int hashCode = data.getArray().hashCode();
 
        // 在线程中修改数据
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    System.out.println("线程开始执行...");
                    data.setArray(new int[]{});
                    System.out.println("线程执行结束");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
 
        while(data.getArray().hashCode() == hashCode) {
            // 如果进入这里,表示不可见
        }
 
        System.out.println("array 是可见的");
    }
 
    public static void main(String[] args) {
        new Demo();
    }
 
}

//运行以上代码,将输出以下信息
线程开始执行...
线程执行结束
array 是可见的

volatile修改数组引用--使其达到指定效果

public class Demo {
    class Data {
        private volatile int[] array = new int[10];
 
        public void setArray(int index, int value) {
            this.array[index] = value;
        }
 
        public int[] getArray() {
            return this.array;
        }
    }
 
    public Demo() {
        final Data data = new Data();
        int hashCode = data.getArray().hashCode();
 
        // 在线程中修改数据
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    System.out.println("线程开始执行...");
                    // 修改数组元素
                    data.setArray(0, 10);
                    System.out.println("线程执行结束");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
 
        while(data.getArray().hashCode() == hashCode) {
            // 如果进入这里,表示不可见
        }
 
        System.out.println("array 是可见的");
    }
 
    public static void main(String[] args) {
        new Demo();
    }
 
}

//运行以上代码,将输出以下信息
线程开始执行...
线程执行结束
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaCourse/202307/6966.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者