多线程(七):AtomicInteger

包括:
一. AtomicInteger 概念,API
二. CAS 算法简介


一. AtomicInteger 概念,API
        我们知道,i++ 操作并不是原子性的,多线程下使用 可能会出现问题。那么AtomicInteger 就可以解决这个问题,利用 AtomicInteger,一个变量的自增可以是原子性的。当然,我们也可以通过 lock 或者 synchronized 等方法正常 使用 i ++。

常用API:

public class AtomicIntegerTest {
	public static void main(String[] args) {
		AtomicInteger a = new AtomicInteger();
		a.incrementAndGet(); //++i
		a.getAndIncrement(); //i++
		a.decrementAndGet(); //--i
		a.getAndDecrement(); //i--
	}
}

二. CAS 算法简介
          AtomicInteger 实现原理:主要通过 CAS 算法。也就是说, 对某个内存值拷贝一个副本,某个线程若读到该副本,并对其进行计算,输出结果,在写入内存时,再次取出内存值和该副本比较,若副本和内存值相同,则把新的值写入内存。
          CAS 算法尽可能的缩小了锁的范围,所有速度效率上会比 Lock,Synchronized 高很多。 现代的CPU提供了特殊的指令,可以自动更新共享数据,而且能够检测到其他线程的干扰,而 compareAndSet() 就用这些代替了锁定。
          CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。 例如一个 ++i 算法:
public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}

          在这里采用了CAS操作,每次从内存中读取数据然后将此数据和+1后的结果进行CAS操作,如果成功就返回结果,否则重试直到成功为止。而compareAndSet利用JNI来完成CPU指令的操作。

缺点:
  1. ABA问题
  2. 循环时间长开销大。自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。
  3. 只能保证一个共享变量的原子操作。当对一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子 操作,但是对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁,或者有一个取巧的办法,就是把多个共享变量合并成一个共享变量 来操作。比如有两个共享变量i=2,j=a,合并一下ij=2a,然后用CAS来操作ij。从Java1.5开始JDK提供了AtomicReference类来保证引用对象之间的原子性,你可以把多个变量放在一个对象里来进行CAS操作。
PS:
  1. ABA 问题: AtomicInteger 可能出现ABA问题,也就是若其中一个线程修改A->B->A,另外一个线程仍然读取到A,虽然值是预期值,但并不能说明该内存值没有变化。ABA问题的解决方案:通过标记或者版本号和每一个CAS操作的值相绑定,并且原子性的更新值和标记来处理这类问题。从Java1.5开始JDK的atomic包里提供了一个类AtomicStampedReference来解决 ABA问题。这个类的compareAndSet方法作用是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方 式将该引用和该标志的值设置为给定的更新值。
  2. 乐观锁 和 悲观锁:独占锁是一种悲观锁,synchronized就是一种独占锁,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁。而另一个更加有效的锁就是乐观锁。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。java.util.concurrent包中借助CAS实现了区别于synchronized悲观锁的一种乐观锁。


参考:
  1. AtomicInteger原理:http://caogen81.iteye.com/blog/2002884
  2. 理解 CAS算法在Java 中的作用:http://www.cnblogs.com/onlywujun/articles/3529572.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值