java并发包-AtomicInteger的并发处理

今天我们研究一下java并发包下面的 AtomicInteger 类

     java.util.concurrent.atomic 包中添加原子变量类。所有原子变量类都公开“比较并设置”原语,这些原语都是使用平台上可用的最快本机结构(比较并交换、加载链接/条件存储,最坏的情况下是旋转锁)来实现的。 java.util.concurrent.atomic  包中提供了原子变量的 9  种风格(AtomicInteger、AtomicLong、 olean、原子整型、长型、及原子标记引用和戳记引用类的数组形式, 其原子地更新一对值)。

 
     AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。
简单的来看一下 AtomicInteger 提供的接口。
public final int get()   //获取当前的值 
public final int getAndSet(int newValue)  //取当前的值,并设置新的值 
public final int getAndIncrement()  //获取当前的值,并自增 
public final int getAndDecrement()  //获取当前的值,并自减 
public final int getAndAdd(int delta)  //获取当前的值,并加上预期的值 ... ... 
 

下面的程序是使用原子变量后的计数器:
package test; 
import java.util.concurrent.atomic.AtomicInteger; 
public class AtomicCounter {   
private AtomicInteger value = new AtomicInteger();   
public int getValue() {    return value.get();  }   
public int increment() {    return value.incrementAndGet();  }   
public int increment(int i) {    return value.addAndGet(i);  }   
public int decrement() {    return value.decrementAndGet();  }   
public int decrement(int i) {    return value.addAndGet(-i);  } } 

下面写一个测试类:
package test;
public class AtomicCounterTest extends Thread {
 AtomicCounter counter;
  public AtomicCounterTest(AtomicCounter counter) {
   this.counter = counter;
 }
  @Override
  public void run() {
   int i = counter.increment();
  System. .println("generated  out number:" + i);
 }
  public static  void main(String[] args) {
  AtomicCounter counter = new AtomicCounter();
   for (int i = 0; i < 10; i++) {//10个线程
    new AtomicCounterTest(counter).start();
  }
 }
} 
  
generated number:1
generated number:2
generated number:3
generated number:4
generated number:5
generated number:7
generated number:6
generated number:9
generated number:10
generated number:8


会发现 10 个线程运行中,没有重复的数字,原子量类使用本机 CAS实现了值修改的原子性。

看到网上一些资料对这个类的一些问题,这里简要摘录几个关键的,尝试解答一下:
1、为什么AtomicInteger里面的compareAndSet和weakCompareAndSet方法实现完全一样,注释说明却不同?
    核心观点就是人家保留更改这个实现的权利。现在一样可能是暂时的,将来可能会不一样,所以使用接口时,还是按照人家接口说明来吧。
2、他比直接使用传统的java锁机制(阻塞的)有什么好处?
     最大的好处就是可以避免多线程的优先级倒置和死锁情况的发生,当然高并发下的性能提升也是很重要的。
3、使用了他,并发环境下就一定没问题了吗?
    在某些场景下,可能会造成业务问题。但是多数的场景(比如高效的计数器实现)是不用担心这个问题的。

好了,暂时写到这里吧,大家有什么不明白的可以直接提问,如果文章有有什么错误大家也及时提出来。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欧米优

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值