zoukankan      html  css  js  c++  java
  • 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可以避免这种错误发生。

     

  • 相关阅读:
    Android(java)学习笔记78:Java类初始化顺序
    Android(java)学习笔记77:Android中assets文件夹资源的访问
    Android(java)学习笔记76:Handler用法总结 和 秒表案例
    Android(java)学习笔记75:ListViewProject案例(ListView + BaseAdapter + CheckBox)
    Android(java)学习笔记74:ListViewProject案例(ListView + ArrayAdapter)
    POJ 2516 Minimum Cost
    POJ 2195 Going Home
    POJ 1087 A Plug for UNIX
    POJ 3281 Dining
    ZUFE OJ 2289 God Wang II
  • 原文地址:https://www.cnblogs.com/kzyuan/p/14441747.html
Copyright © 2011-2022 走看看