JUC之AtomicInteger

JUC之AtomicInteger

我们知道在线程中++i和i--是线程不安全的,我们首先想到的可能就是synchronized关键字。

低并发情况下:使用AtomicInteger,因为其是基于乐观锁,并发低。

高并发情况下:使用synchronized,如果使用AtomicInteger,程序消耗资源会增大,甚至很可能失败,因为:

 public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } 
        //如果失败就一直尝试,等待直到成功
        while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }
public class TestAtomicDemo {

    public static void main(String[] args) {
        AtomicDemo ad = new AtomicDemo();

        for (int i = 0; i < 5; i++) {
            //开启线程
            new Thread(ad).start();
        }
    }
}

//写一个类实现Runable接口
class AtomicDemo implements Runnable {
    /*
    * AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,
    * ++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。
    * 而AtomicInteger则通过一种线程安全的加减操作接口。
    * 底层是volatile关键字
    * */
    private AtomicInteger serialNumber = new AtomicInteger();
    /*源码解析
    * public class AtomicInteger extends Number implements java.io.Serializable {
    * 实现序列化接口
    private static final long serialVersionUID = 6214790243416807050L;

    // setup to use Unsafe.compareAndSwapInt for updates (使用CAS算法)
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }
    *
    * volatile修饰变量
    * private volatile int value;
    * */

    @Override
    public void run() {

        System.out.println(getNumber());
        System.out.println("-------");
    }

    public int getNumber() {

        //自增
        //return serialNumber.getAndIncrement();
        return serialNumber.getAndDecrement();//自减
    }


}
posted @ 2021-05-25 20:23  努力加油天天向上  阅读(60)  评论(0编辑  收藏  举报