【问题标题】:AtomicIntegerArray vs AtomicInteger[]AtomicIntegerArray 与 AtomicInteger[]
【发布时间】:2009-03-28 12:13:57
【问题描述】:

AtomicIntegerArrayAtomicInteger[]的含义有区别吗? 哪一个使用起来更快? (我唯一注意到的是 first 占用的空间要少得多,但这意味着每次重新检查都会检查数组的边界,这样会使其变慢吗?)

编辑:在数组预初始化的情况下。

【问题讨论】:

    标签: java concurrency atomic-values


    【解决方案1】:

    AtomicInteger[] 每个元素都需要一个对象。 AtomicIntegerArray 只需要 AtomicIntegerArray 对象和一个数组对象。所以尽可能使用后者。

    即使对于普通数组,边界检查的成本也很小。可能重要的是,从多个处理器访问同一高速缓存行中的数据可能会导致严重的性能问题。因此,单独的对象,或故意避免数组中的紧密元素会有所帮助。

    【讨论】:

    • 谁在乎边界检查?如果您查看 getAndSet 的(明显)源代码,它会为 get 和 compareAndSet 进行地址计算(尽管比这更糟糕,大多数处理器可以在没有 cas 的情况下进行 get-and-set)。
    • tnx (没有看到你的第二段)所以最好不要同时创建所有对象? (或随机顺序?)
    • (我做了一个快速编辑。)在不同时间创建对象不会有帮助,因为 GC 会重新排列它们。 java.util.concurrent 中的一个类甚至可以添加大量填充(在最近的版本中)。向 AtomicIntegerArray 添加填充元素应该更容易和更清晰,只需向左移动即可。
    【解决方案2】:
    • AtomicInteger[] 是一个线程安全整数数组。
    • AtomicIntegerArray 是线程安全的整数数组。

    【讨论】:

      【解决方案3】:

      在下面,AtomicInteger 和 AtomicIntegerArray 通常使用相同的低级 API 来执行读取、写入和其他 CAS 操作。 (例如,OpenSDK 7 使用sun.misc.Unsafe 在两个类中执行 CAS 操作。)因此使用 AtomicInteger[] 几乎没有性能优势。正如您已经注意到的,使用 AtomicIntegerArray 确实具有显着的内存优势。

      实际上,使用后者也使您不必构建所有 AtomicInteger 实例。请记住,由于并发原因,您不能天真地懒惰地分配它们;您将不得不预先分配或使用一些安全的发布机制。所以除了内存优势,你的代码更干净。

      类似地,如果您有一堆具有 AtomicInteger 成员的对象,例如:

      class ReadCounter {
        private final String _fileName;
        private final AtomicInteger _readCount;
        ...
      }
      
      private final Map<String, ReadCounter> _counterByName = ...;
      

      然后您可以通过将成员变量_readCount 建模为volatile int 并使用AtomicIntegerFieldUpdater 来实现类似的内存改进。

      【讨论】:

      • 更新程序操作的速度较低(尽管 get 和 set 速度很快)。有时值得将 Atomic* 扩展为一种节省内存的技巧。
      【解决方案4】:

      我同意Tom Hawtin's first paragraph...

      AtomicInteger[] 每个元素都需要一个对象。 AtomicIntegerArray 只需要 AtomicIntegerArray 对象和一个数组对象。所以尽可能使用后者。

      ...但也应该注意AtomicInteger[] 不是线程安全的。具体来说,如果从多个线程访问,数组对单个 AtomicInteger 对象的引用可能正确,也可能不正确。不过,同步对数组对象本身的访问将消除此问题。

      【讨论】:

      • 关于 Atomic* 的要点是避免同步。 AtomicInteger[] 的假定使用方法是创建一次所有 AtomicInteger,然后才安全地发布数组。
      • 我同意。我不是在提倡使用 AtomicInteger[],只是注意到不同之处,这就是问题所在:)
      猜你喜欢
      • 2010-11-30
      • 2013-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多