• Volatile的3大特性


    Volatile

      volatile是Java虚拟机提供的轻量级的同步机制

     

    3大特性

    1.保证可见性

    当多个线程同时访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值

    案例代码

    import java.util.concurrent.TimeUnit;
     ​
     class MyData {
     //    int number = 0;
         volatile int number = 0;
     ​
         public void add() {
             this.number = 60;
         }
     }
     ​
     public class VolatileDemo {
         public static void main(String[] args) {
             MyData myData = new MyData();
     ​
             new Thread(() -> {
                 System.out.println(Thread.currentThread().getName() + "	 come in");
                 try {
                     // 暂停一下线程
                     TimeUnit.SECONDS.sleep(3);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
                 myData.add();
                 System.out.println(Thread.currentThread().getName() + "	 updated number value:" + myData.number);
             }, "AAA").start();
     ​
             // 第2个线程就是main线程
             while (myData.number == 0) {
                 // main线程一直在这里等待循环,直到number != 0
             }
     //        System.out.println(Thread.currentThread().getName()+"	 mission is over");
             System.out.println(Thread.currentThread().getName() + "	 mission is over, number value:" + myData.number);
         }
     }
    结果:
      AAA  come in
      AAA  updated number value:60
     ​
    加了volatile关键字的结果:
       AAA  come in
       AAA  updated number value:60
       main     mission is over, number value:60

    2.不保证原子性

    原子性:一个操作或多个操作要么全部执行完成且执行过程不被中断,要么就不执行

    案例代码

     import java.util.concurrent.TimeUnit;
     ​
     class MyData {
         volatile int number = 0;
     ​
         public void add() {
             this.number = 60;
         }
     ​
         // 此时number是有volatile修饰的
         public void addPlus() {
             number++;
         }
     }
     ​
     public class VolatileDemo {
         public static void main(String[] args) {
             MyData myData = new MyData();
     ​
             for (int i = 1; i <= 20; i++) {
                 new Thread(() -> {
                     for (int j = 1; j <= 1000; j++) {
                         myData.addPlus();
                     }
                 }, String.valueOf(i)).start();
             }
     ​
             while (Thread.activeCount() > 2) {
                 Thread.yield();
             }
     ​
             System.out.println(Thread.currentThread().getName() + "	 finally number value:" + myData.number);
     ​    }
     }
    结果:
    main finally number value:19909 main finally number value:18330 main finally number value:19904
    结论:每次运行结果都不相同,所以volatile不保证原子性

    3.禁止指令重排

    指令重排序:是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。

    在Jvm执行中,指令重排在多个线程同时访问一个普通变量的情况下,可能导致程序执行结果发视错误,而volatile可以避免这种错误发生。

     

  • 相关阅读:
    证书格式转换
    emq知识点
    emq共享订阅
    SpringBoot
    Android网络编程Socket长连接
    Android 网络通信框架Volley简介(Google IO 2013)
    Android中的5种数据存储方式
    Android
    android解析XML总结(SAX、Pull、Dom三种方式)
    乔迁新禧
  • 原文地址:https://www.cnblogs.com/kzyuan/p/14441747.html
Copyright © 2020-2023  润新知