zoukankan      html  css  js  c++  java
  • volatile的理解

    一。volatile是java虚拟机提供的轻量级的同步机制

          1.保证可见性

      1.1 假如 int number = 0;number变量之前没有添加volatile,没有可见性,不会走到第三步
    1.2 number变量之前添加volatile,具有可见性,3秒之后会走到第三步
     1 class MyData {
     2     volatile int number = 0;
     3 
     4     public void addTo60() {
     5         this.number = 60;
     6     }
     7 }
     8 
     9 public class VolatileDemo {
    10     public static void main(String[] args){
    11         seeOkByVolatile();
    12     }
    13     public static void seeOkByVolatile() {
    14         MyData myData = new MyData();
    15         new Thread(() -> {
    16             System.out.println(Thread.currentThread().getName()+" start");// 第一步
    17             try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
    18             myData.addTo60();
    19             System.out.println(Thread.currentThread().getName()+" update end value: "+myData.number);// 第二步
    20         }, "AAA").start();
    21 
    22         while (myData.number == 0) {
    23 
    24         }
    25         System.out.println(Thread.currentThread().getName()+" value:"+myData.number);// 第三步
    26     }
    27 
    28 
    29 }

        2.不保证原子性

      结果:输出小于20000

      原因:number++这个操作实际上可以分为3个步骤

        1.从主内存中读取number=0的值,复制到工作内存中

        2.在工作内存中进行加1操作

        3.将加1后的值赋给主内存

      分析:有两个线程T1,T2同时进行number++操作时,当T1进行完1,2,3步骤后 number=1,T2刚执行完1,2还没有执行完3(number = 0 + 1)number=1

         有重新赋值给主内存,导致两个线程都对number加1,最终只增加了1次。

      方案:怎么保证原子性

        1.使用 synchronized

     1 class MyData {
     2     volatile int number = 0;
     3     public void addPluxPlux() {
     4         number++;
     5     }
     6 }
     7 public class VolatileDemo {
     8     public static void main(String[] args){
     9         MyData myData = new MyData();
    10         for (int i = 0; i < 20; i++) {
    11             new Thread(() -> {
    12                 for (int j = 0; j < 1000; j++) {
    13                     myData.addPluxPlux();
    14                 }
    15             },String.valueOf(i)).start();
    16         }
    17         while(Thread.activeCount() > 2){
    18             Thread.yield();
    19         }
    20         System.out.println("number: "+myData.number); 
    21     }
    22 }

         2.使用原子类AtomicInteger

        输出结果:number<20000,atomic=20000

     1 class MyData {
     2     volatile int number = 0;
     3     public void addTo60() {
     4         this.number = 60;
     5     }
     6     public void addPluxPlux() {
     7         number++;
     8     }
     9 
    10     AtomicInteger atomic = new AtomicInteger();
    11     public void atomicAddPlux(){
    12         atomic.incrementAndGet();
    13     }
    14 }
    15 
    16 public class VolatileDemo {
    17     public static void main(String[] args){
    18         MyData myData = new MyData();
    19         for (int i = 0; i < 20; i++) {
    20             new Thread(() -> {
    21                 for (int j = 0; j < 1000; j++) {
    22                     myData.addPluxPlux();
    23                     myData.atomicAddPlux();
    24                 }
    25             },String.valueOf(i)).start();
    26         }
    27 
    28         while(Thread.activeCount() > 2){
    29             Thread.yield();
    30         }
    31         System.out.println("number: "+myData.number);
    32         System.out.println("atomic: "+myData.atomic);
    33 
    34     }
    35 }

        3.禁止指令重排

      指令重排必须要考虑指令之间的数据依赖性

  • 相关阅读:
    Search for a Range 分类: Leetcode(查找) Leetcode(排序) 2015-04-10 15:34 23人阅读 评论(0) 收藏
    First Missing Positive 分类: Leetcode(排序) 2015-04-09 17:13 25人阅读 评论(0) 收藏
    Insertion Sort List 分类: Leetcode(排序) 2015-04-09 11:26 23人阅读 评论(0) 收藏
    Merge k Sorted Lists 分类: Leetcode(树) 2015-04-09 09:35 17人阅读 评论(0) 收藏
    Merge Two Sorted Lists 分类: Leetcode(排序) 2015-04-08 21:59 24人阅读 评论(0) 收藏
    Merge Sorted Array 分类: Leetcode(排序) 2015-04-08 21:52 24人阅读 评论(0) 收藏
    Sum Root to Leaf Numbers 分类: Leetcode(树) 2015-04-04 21:25 27人阅读 评论(0) 收藏
    计算机网络数据链路层次学习
    ArrayList总结及部分源码分析
    抽象类基本概念
  • 原文地址:https://www.cnblogs.com/zcjyzh/p/14336129.html
Copyright © 2011-2022 走看看