juc-2-原子变量与CAS算法

 
i++的原子性问题
例子   int i=10;
          i++;
结果   i=10
 
分析过程    
               在计算机 底层 会有生成一个临时变量 temp  将i的值赋值给temp
              int i=10;    ------>      int temp =i;
               i++;          ------>        i=i+1;
                   最后      ------>      i=temp;
 
            总结 i++ 过程中  读->改->写的操作
 
volatile 只能保证读的数据一样  不能保证改->写的操作 的数据一致   所以不能保证线程安全的原子性
 
原子变量:在 java.util.concurrent.atomic 包下提供了一些原子变量。
原子变量使用volatile修饰
 
原子变量使用了volatile 和CAS算法
*         1. volatile 保证内存可见性   不能保证原子性   原子性指不可分割
*         2. CAS(Compare-And-Swap) 算法保证数据变量的原子性
*             CAS 算法是硬件对于并发操作的支持
*             CAS 包含了三个操作数:
*             ①内存值  V
*             ②预估值  A
*             ③更新值  B
*             当且仅当 V == A 时, V = B; 否则,不会执行任何操作。(保证了原子性)
 
仅仅使用volatile关键字修饰变量
仅仅使用volatile关键字  出现了违背线程安全的原子性
 
正确的做法  使用原子变量  满足 线程安全的原子性  可见性
 
 1 package com.wf.zhang.juc;
 2 
 3 import java.util.concurrent.atomic.AtomicInteger;
 4 
 5 public class TestAtomicDemo {
 6 
 7 
 8     public static void main(String[] args) {
 9         AtomicDemo ad = new AtomicDemo();
10 
11         for (int i = 0; i < 10; i++) {
12             new Thread(ad).start();
13         }
14     }
15 
16 }
17 
18 class AtomicDemo implements Runnable{
19 
20     //private volatile int serialNumber = 0;
21 
22     private AtomicInteger serialNumber = new AtomicInteger(0);
23 
24     @Override
25     public void run() {
26 
27         try {
28             Thread.sleep(200);
29         } catch (InterruptedException e) {
30         }
31 
32         System.out.println(getSerialNumber());
33     }
34 
35     public int getSerialNumber(){
36 
37         //return serialNumber++;
38 
39         return serialNumber.getAndIncrement(); //得到值并且自增
40     }
41 
42 
43 }
View Code

 

 
posted @ 2019-11-24 12:43  wf.zhang  阅读(209)  评论(0编辑  收藏  举报