Java中关于atomic的理解及使用示例

atomic对于数据原子性操作较方便处理,即当多个线程对同一个变量进行更新时,仅有一个线程可以成功,而未能成功的形成会像自旋锁一样,继续尝试,一直等到执行成功。

原子性原理:

 
 一、i++的原子性,i++的操作,分为三部分:"读-改-写"
            int i = 10;
            i = i++; //10
       
            int temp = i;
            i = i + 1;
            i = temp;
       
 二、原子变量:java.util.concurrent.atomic包下提供了常用的原子变量
           1.volatile 保证内存可见性
           2.CAS(Compare-And-Swap)算法保证数据的原子性
             CAS算法是硬件对于并发操作共享数据的支持。
             CAS包含了三个操作数:
                内存值:V
                预估值:A
                更新值:B
                当且仅当V == A, V = B,否则,不做任何操作。

嗯~~~理解以及使用直接上代码………………

3 import java.util.concurrent.atomic.AtomicInteger;
  4 import java.util.function.DoubleUnaryOperator;
  5 import java.util.function.IntUnaryOperator;
  6 import static java.lang.Float.*;
  7 
  8 public class AtomicPrac {
  9     public static void main(String[] args) {
 10         AtomicDemo atomicDemo = new AtomicDemo();
 11         atomicDemo.setNumberA(new AtomicInteger(3));
 12         for (int i = 1; i <= 10; i++) {
 13             new Thread(atomicDemo).start();
 14         }
 15         
 16         AtomicInteger j=new AtomicInteger(4);
 17         System.out.println(j.incrementAndGet());
 18         System.out.println(updateAndGetInt(j,p -> p/2 ));
 19         
 20         //double型数据
 21         AtomicFloat k = new AtomicFloat(5);
 22         System.out.println(updateAndGetDouble(k,p -> p/2 ));
 23         
 24     }
 25     //模拟底层实现:
 26     public static float updateAndGetDouble(AtomicFloat i, DoubleUnaryOperator operator){
 27         while(true){
 28             float prev=i.get();//得到当前值
 29             float next=(float) operator.applyAsDouble(prev);//将旧值传入,让接口的某个方法完成具体运算,返回计算结果
 30             //重写compareAndSet
 31             if(i.compareAndSet(prev,next)){
 32                 return next;
 33             }
 34         }
 35     }
 36     public static int updateAndGetInt(AtomicInteger i, IntUnaryOperator operator){
 37         while(true){
 38             int prev=i.get();//得到当前值
 39             int next=operator.applyAsInt(prev);//将旧值传入,让接口的某个方法完成具体运算,返回计算结果
 40             if(i.compareAndSet(prev,next)){
 41                 return next;
 42             }
 43         }
 44     }
 45     //模拟底层实现:
 46 }
 47 class AtomicDemo implements Runnable {
 48     public AtomicInteger numberA;
 49     
 50     public void run() {
 51         try {
 52               Thread.sleep(200);
 53         } catch (InterruptedException e) {
 54               e.printStackTrace();
 55         }
 56           System.out.println(Thread.currentThread().getName() + ":" + getNumberA());
 57     }
 58 
 59     public int getNumberA() {
 60         return numberA.updateAndGet(x -> x*2);
 61     }
 62 
 63     public void setNumberA(AtomicInteger numberA) {
 64         this.numberA = numberA;
 65     }
 66 }
 67 
 68 //对于使用双精度型的数据对应AtomicLong 自定义AtomicDouble   转换doubleToLongBits(1.00);
 69 //对于使用单精度型的数据对应AtomicInteger 自定义AtomicFloat   转换floatToIntBits(1.00);
 70 class AtomicFloat extends Number {
 71     
 72     private AtomicInteger bits;
 73     
 74     public AtomicFloat() {
 75         this(0f);
 76     }
 77     
 78     public AtomicFloat(float initialValue) {
 79         bits = new AtomicInteger(floatToIntBits(initialValue));
 80     }
 81     
 82     public final boolean compareAndSet(float expect, float update) {
 83         return bits.compareAndSet(floatToIntBits(expect),
 84                 floatToIntBits(update));
 85     }
 86     
 87     public final void set(float newValue) {
 88         bits.set(floatToIntBits(newValue));
 89     }
 90     
 91     public final float get() {
 92         return intBitsToFloat(bits.get());
 93     }
 94     
 95     public float floatValue() {
 96         return get();
 97     }
 98     
 99     public final float getAndSet(float newValue) {
100         return intBitsToFloat(bits.getAndSet(floatToIntBits(newValue)));
101     }
102     
103     public final boolean weakCompareAndSet(float expect, float update) {
104         return bits.weakCompareAndSet(floatToIntBits(expect),
105                 floatToIntBits(update));
106     }
107     
108     public double doubleValue() { return (double) floatValue(); }
109     public int intValue()       { return (int) get();           }
110     public long longValue()     { return (long) get();          }
111 }

运行结果:

5
2
2.5
Thread-0:6
Thread-1:12
Thread-4:24
Thread-9:192
Thread-8:384
Thread-3:768
Thread-2:96
Thread-5:48
Thread-6:3072
Thread-7:1536

posted @ 2020-07-09 11:07  radiant13  阅读(1126)  评论(0编辑  收藏  举报