AtomicInteger源码

CAS是实现并发计算时常用到的技术,是一条CPU的原子指令,不会存在线程安全问题
CAS操作包含三个操作数:内存值V,预期值A,更新值B。当且仅当预期值A和内存值V相等时,才会将内存值V修改为更新值B。否则不做任何操作,多线程同时执行CAS操作只有一个会成功
Unsafe是CAS的核心类,由于Java无法直接访问底层系统,需要通过Native方法来访问,因此Java中的CAS操作的执行都依赖于Unsafe类的方法

AtomicInteger

public class AtomicInteger extends Number implements Serializable {
	private static final long serialVersionUID = 6214790243416807050L;
	private static final Unsafe unsafe = Unsafe.getUnsafe();//初始化Unsafe类
	private static final long valueOffset;//value成员变量的内存偏移量
	private volatile int value;//当前value值
	
	static {
		try {
			//初始化valueOffset
			valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
		} catch (Exception var1) {
			throw new Error(var1);
		}
	}
}

AtomicInteger中的getAndIncrement()

	public final int getAndIncrement() {
		return unsafe.getAndAddInt(this, valueOffset, 1);
	}

Unsafe中的getAndAddInt()

	public final int getAndAddInt(Object var1, long var2, int var4) {
		int var5;
		do {
			//根据当前对象this和内存偏移量valueOffset获取变量的当前内存值
			var5 = this.getIntVolatile(var1, var2);
			//当且仅当预期值和内存值相等时,将内存值修改为更新值,否则一直自旋
		} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

		return var5;
    }

CAS两大缺点

1.循环时间长开销大:自旋CAS如果长时间不成功,会给CPU带来很大的开销
2.ABA问题:线程1读取到的内存值是A,线程2读取到的内存值也是A;当线程2将内存值修改为B,再将内存值修改为A;线程1修改内存值的时候发现内存中仍然是A,符合预期。尽管在某些业务中只要前后值一样,对最终的结果就不会有影响;但在某些特殊的业务中变量在中间过程是不能被修改的,因此可以使用版本号机制解决ABA问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值