AtomicInteger

AtomicInteger阅读笔记

问题

1、什么是原子操作?

  • 一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样

2、什么是可见性?

  • 可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

3、AtomicInteger通过什么实现原子操作?

  • 通过Unsafe原子工具类来实现原子操作

4、AtomicInteger有什么缺点?

  • 有ABA问题,且自旋消耗CPU性能

一、简介

优点:

  • CAS乐观锁,性能较强,利用CPU自身的特性保证原子性,即CPU的指令集封装CompareAndSwap两个操作为一个指令来保证原子性。
  • 适合读多写少模式。

缺点:

  • 自旋,消耗CPU性能,所以写的操作较多推荐sync(悲观锁)
  • 仅适合简单的运算,否则会 产生ABA问题,自旋的时候,别的线程可能更改value,然后又更改回来,此时需要加版本号解决,JDK提供了AtomicStampedReference和AtomicMarkableReference解决ABA问题,提供基本数据类型和引用数据类型版本号支持

二、继承关系图

1、继承Number抽象类、实现Serializable接口

2、函数列表
C:\Users\86134\AppData\Local\Temp\1577238960051.png

三、存储结构

  • 支持并发的Integer存储结构,大部分都是final方法

四、源码分析

内部类
属性
  • Unsafe:工具
  • value:int值
  • valueOffset:内存偏移地址
构造
  • public AtomicInteger()
    • 实例化AtomicInteger
  • public AtomicInteger(int initialValue) {value = initialValue;}
    • 实例化AtomicInteger 且初始化value。
主要方法
  • public final int getAndAdd(int delta){ return unsafe.getAndAddInt(this, valueOffset, delta);}
    • 返回当前value,在内存中对value进行加delta,
  • public final int addAndGet(int delta){ return unsafe.getAndAddInt(this, valueOffset, delta) + delta;}
    • 在内存中对value进行加delta,然后返回原value+delta的和。
  • public final int getAndDecrement(){ return unsafe.getAndAddInt(this, valueOffset, -1);}
    • 返回当前value,然后对value-1,类似i–;
  • public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1);}
    • 返回当然value,然后对value+1,类似i++;
  • public final int decrementAndGet() {return unsafe.getAndAddInt(this, valueOffset, -1) - 1;}
    • 在内存中对value进行-1,然后返回的值,类似–i;
  • public final int incrementAndGet() {return unsafe.getAndAddInt(this,valueOffset, 1) + 1;}
    • 在内存中对value进行+1,然后返回新的值,类似++i;
  • public final int getAndSet(int newValue) { return unsafe.getAndSetInt(this, valueOffset, newValue);}
    • 返回当前value,然后把value更新为newValue,采用cas
  • public final void set(int newValue) {value = newValue;}
    • 更新value为newValue。立即修改旧值,别的线程可以立马看到新值
  • public final void lazySet(int newValue){unsafe.putOrderedInt(this,valueOffset, newValue);}
    • 更新value为newValue。不能保证其他线程能立即看到修改的值,但最终会看到
补充
//获取Unsafe工具
private static final Unsafe unsafe = Unsafe.getUnsafe();
//value值在AtomicInteger对象中的偏移量,用于读写操作
private static final long valueOffset;
static {
    try {
        //初始化valueOffset
        //使用反射获得value字段的Field,然后调用unsafe工具类的objectFieldOffset(获取非静态属性在对象中的偏移量)。
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
    } catch (Exception ex) { throw new Error(ex); }
}

//Unsafe包中的getAndAddInt
public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);//使用volatile方式获取值
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));//循环更新值,失败继续

    return var5;
}

五、总结

主要大量运用了Unsafe类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值