JAVA并发编程的三大特性之一:原子性AtomicInteger

在java并发编程中,如果想要保证程序的线程安全,就要保证代码的原子性,可见性,有序性

Java本身的原子性

        由java内存模型来直接保证具有原子性变量操作的有 read/load/use/assign/store/write.

java提供了原子性的技术保障有如下:

1.synchronized(互斥锁)

2.Lock(互斥锁)

3.原子类(CAS)

以上两个都是通过互斥锁实现,即同一时刻只允许一个线程来操作该变量,保障了原子性.                上两种也被称为悲观锁  CAS为乐观锁

AtomicInteger  以原子的方式更新int值

public AtomicInteger()                创建具有初始值  0  的新AtomicInteger.

public AtomicInteger(int i)          创建具有给定初始值的新 AtomicInteger.

方法

        int getAndIncrement()         以原子方式将当前值加1        i++.

        int incrementAndGet()        以原子方式将当前值加1        ++i.

        int getAndDecrement()        以原子方式将当前值减1        i--.

        int decrementAndGet()        以原子方式将当前值减1        --i.

        int get()        获取当前值

        int intValue()    获取当前值

        

        int getAndAdd(int delta)        以原子方式将给定值与当前值相加        先获取,加相加 与 i++相似

        int addAndGet(int delta)        以原子方式将给定值与当前值相加        先相加在获取 与++i相似

原理

CAS无锁机制        比较并替换

当多条线程尝试使用CAS同时更新同一个变量时,只有其中一条线程能更新变量的值,而其他线程都失败,失败的线程并不会被挂起,而是告知这次竞争失败,并可以再次尝试.

        

缺点

  1. 循环时间长开销很大。

    CAS 通常是配合无限循环一起使用的,如果 CAS 失败,会一直进行尝试。如果 CAS 长时间一直不成功,可能会给 CPU 带来很大的开销。
  2. 只能保证一个变量的原子操作。

    当对一个变量执行操作时,我们可以使用循环 CAS 的方式来保证原子操作,但是对多个变量操作时,CAS 目前无法直接保证操作的原子性。
  3. ABA问题。

    第一条线程获取到V位置的值  假设是 1
    第二条线程获取到V位置的值  也是1
    第一条线程cas成功 将值改为 0
    第一条线程又cas成功 将值改回 1
    这时第二条线程cas 发现值没变 还是1 cas成功   
    实际上当第二条线程cas时 V位置的值已经从 1-0-1
    这就是ABA问题 
    如何解决 每次获取V位置的值时,带上一个版本号.这样就可以避免ABA问题 java中AtomicStampedReference这个类在cas时就是通过版本号来解决的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值