JUC-原子类(AtomicInteger)

版权声明:版权所有,翻版我也没办法!!! https://blog.csdn.net/tebtebtebteb/article/details/82964699

引入:

我们都知道i++在java中不是原子操作,因为i++的操作实际上分为三个步骤“读-改-写”,

int i =10;
i = i++;

实际上是分为下面几步:

int temp = i;
i = i + 1;
i = temp;

反编译后可以看到每条指令都会产生一个get和put,它们之间还有一些其他的指令。因此在获取和放置之间,另一个任务可能会修改这个域,所以这些操作不是原子性的。

JavaSE5引入了诸如AtomicInteger、AtomicLong、AtomicReference等特殊的原子性变量类,可以实现原子操作。它们提供下面形式的原子性条件更新操作:

boolean compareAndSet(expectedValue,updateValue);

这个被称作CAS(Compare-And-Swap) :比较并交换,该算法是硬件对于并发操作的支持。

CAS包含了三个操作数:

①内存值  V

②预估值  A

③更新值 B

当前仅当V == A时,V = B,否则不会执行任何操作。

 模拟CAS算法:

package com.tongtong.app5;

/**
 *模拟CAS算法
 */
public class TestCompareAndSwap {

    public static void main(String[] args) {
        final CompareAndSwap cas = new CompareAndSwap();

        for(int i = 0;i < 10; i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    int expectedValue = cas.get();
                    boolean b = cas.compareAndSet(expectedValue,(int)(Math.random()*101));
                    System.out.println(b);
                }
            }).start();
        }
    }
}

class CompareAndSwap{

    private int value;

    //获取内存值
    public synchronized int get(){
        return value;
    }

    //比较
    public synchronized int compareAndSwap(int expectValue,int newValue){
        int oldValue = value;

        if(oldValue == expectValue){
            this.value = newValue;
        }

        return oldValue;
    }

    //设置
    public synchronized boolean compareAndSet(int expectValue,int newValue){
        return expectValue == compareAndSwap(expectValue,newValue);
    }
}

原子类操作:

package com.tongtong.app6;

import java.util.concurrent.atomic.AtomicInteger;

public class TestAtomicDemo {

    public static void main(String[] args) {

        AtomicDemo ad = new AtomicDemo();

        for(int i = 0;i < 10; i++){
            new Thread(ad).start();
        }
    }
}

class AtomicDemo implements Runnable{

    private AtomicInteger serialNumber = new AtomicInteger(0);

    @Override
    public void run() {

        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(getSerialNumber());
    }

    public int getSerialNumber(){

        return serialNumber.getAndIncrement(); //加1,相当于i++
    }
}

若想更多的了解原子操作,可以进入以下链接进行学习:

http://www.cnblogs.com/xrq730/p/4976007.html

猜你喜欢

转载自blog.csdn.net/tebtebtebteb/article/details/82964699