加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 为什么AtomicReference CAS返回false值为128?

发布时间:2020-12-14 05:39:21 所属栏目:Java 来源:网络整理
导读:我使用AtomicReference来实现AtomicInteger.然而,在测试中,我注意到即使在单线程环境中,一旦其值达到128,CAS操作就会卡住.我做错了什么或在AtomicReference中有一个警告(可能与CPU有关)?这是我的代码: public class MyAtomInt { private final AtomicRefer
我使用AtomicReference来实现AtomicInteger.然而,在测试中,我注意到即使在单线程环境中,一旦其值达到128,CAS操作就会卡住.我做错了什么或在AtomicReference中有一个警告(可能与CPU有关)?这是我的代码:
public class MyAtomInt {
  private final AtomicReference<Integer> ref;

  public MyAtomInt(int init) {
    ref = new AtomicReference<Integer>(init);
  }

  public MyAtomInt() {
    this(0);
  }

  public void inc() {
    while (true) {
      int oldVal = ref.get();
      int nextVal = oldVal + 1;
      boolean success = ref.compareAndSet(oldVal,nextVal); // false once oldVal = 128
      if (success) {
        return;
      }
    }
  }

  public int get() {
    return ref.get();
  }

  static class Task implements Runnable {

    private final MyAtomInt myAtomInt;
    private final int incCount;

    public Task(MyAtomInt myAtomInt,int cnt) {
      this.myAtomInt = myAtomInt;
      this.incCount = cnt;
    }

    @Override
    public void run() {
      for (int i = 0; i < incCount; ++i) {
        myAtomInt.inc();
      }
    }
  }

  public static void main(String[] args) throws Exception {
    MyAtomInt myAtomInt = new MyAtomInt();
    ExecutorService exec = Executors.newSingleThreadExecutor();
    exec.submit(new Task(new MyAtomInt(),150)).get();
    System.out.println(myAtomInt.get());
    exec.shutdown();
  }
}

解决方法

这样做的原因是当您将int装入Integer时,您可能会也可能不会创建新的Integer实例.如果这样做,则新实例可能与其他Integer实例没有引用相等,即使它们共享相同的值. AtomicReference.compareAndSet()使用引用相等(标识)进行比较.

关键在于编译器如何处理int值的自动装箱:它发出对Integer.valueOf()的调用.作为优化,Integer.valueOf()具有盒装整数的缓存,默认情况下,缓存包含最多128的值.如果您将整数n包装两次,如果值很小,则每次都会得到相同的整数引用足以进入缓存;否则,您将获得两个单独的实例.

目前,您取消装入旧值,计算新值,并在调用compareAndSet()时再次装入旧值.一旦达到128,就会停止获取缓存值,因此第二个盒装副本不再与AtomicReference中的副本相同.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读