首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“更好”。AtomicIntegerArray (1/0为真/假)对AtomicBoolean[]?

“更好”。AtomicIntegerArray (1/0为真/假)对AtomicBoolean[]?
EN

Stack Overflow用户
提问于 2014-03-06 21:57:39
回答 3查看 2.4K关注 0票数 10

我对此很好奇。如果使用值为0和1的AtomicIntegerArray,则可以完成与AtomicBoolean数组相同的操作。示例:

代码语言:javascript
复制
final AtomicIntegerArray array1 = new AtomicIntegerArray(10);
array1.compareAndSet(3, 0, 1); // 0 = false and 1 = true

// exactly the same thing of:

final AtomicBoolean[] array2 = new AtomicBoolean[10];
for(int i = 0; i < array2.length; i++)
     array2[i] = new AtomicBoolean(false);
array2[3].compareAndSet(false, true);

你认为哪个更快更好?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-03-06 22:14:08

你认为哪个更快更好?

有趣的问题。这个速度可能只有在你做一些非常多的循环时才是可见的。否则,担心它就像是过早的优化。我会选择最干净和最容易维护的模式。

在幕后,两种方法都使用Unsafe.compareAndSwapInt(...),因此性能可能非常相似。由于对volatile存储的访问没有阻塞,所以这与冲突无关。AtomicBoolean数组肯定会有更多与其关联的对象--每个对象都有自己的易失性存储。此外,在幕后,AtomicBooleanboolean值存储为int,这样就不会节省任何费用。

我的直觉告诉我要使用AtomicIntegerArray。编写的代码较少,这通常意味着更多地依赖JDK来做正确的事情。要想弄清楚这一点,您必须在生产架构上测试大量迭代才能确定。我怀疑这种差别是可以忽略不计的,而且很难测量。

不是一个很好的答案,但希望这里有帮助。

编辑:

所以我只是做了一些测试,我看不出有什么明显的差别。这是我的小测试程序。它使用了100个线程,运行了1000万次迭代,它们之间的距离在0-10%以内。正如@mttdbrd所指出的,这绝不是一个“现实生活”测试。只有在生产过程中使用实际像它那样工作的代码时,才能真正了解两者之间是否有区别。

编辑:

好的,在调整我的程序以确保我将hotspot编译器放在@mttdbrd的文档中,并更改程序以便更好地调优条目的数量之后,我看到了一些有趣的结果。

数组中有1000个元素:

代码语言:javascript
复制
AtomicIntegerArray in 4224 millis
AtomicBoolean[]    in 3546 millis    (always a little bit faster)

但是,在数组中有10个元素:

代码语言:javascript
复制
AtomicIntegerArray in 26506 millis
AtomicBoolean[]    in 13263 millis  (much faster)

还注意到了速度的差异。这是有意义的,因为有更多的线程争用。100个线程更可能需要使用10个元素而不是1000个元素来旋转。

这是什么意思?如果您从一次更改到另一次,您最多可以节省每次操作的1 纳秒。也许吧。因此,与其担心两者的性能,不如选择最干净、最容易维护的模式。

票数 12
EN

Stack Overflow用户

发布于 2014-03-06 22:02:10

实际监视AtomicIntegerArray的实现

http://fuseyism.com/classpath/doc/java/util/concurrent/atomic/AtomicIntegerArray-source.html

它似乎是用比我想的更多的注意力来管理的。

它不使用对象来存储值,从而使其在内存中更有效。实际上,它使用一个简单的int[],然后以一种安全的方式访问它们。

因此,我认为,如果您需要使用许多AtomicInteger,最好使用AtomicIntegerArray。

AtomicIntegerArray:使用不安全类对AtomicIntegerArray中的单个int[]进行原子访问

AtomicBoolean[]:数组的每个对象都有它的对象(本身)来进行原子访问

因此,我希望在具有AtomicBoolean[]的重并发线程环境中获得更好的性能,并且比AtomicIntegerArray占用更多的内存。

票数 3
EN

Stack Overflow用户

发布于 2015-05-24 10:32:01

我想说的是,这两者都是同样的表演,除非激烈的竞争。正如格雷的基准显示的那样,AtomicBoolean[]轻松战胜了AtomicIntegerArray。缺少的是这样的解释:

AtomicIntegerArray在其内部int[]上操作时,将所有int的位置放在一起,而AtomicBoolean[]是一个包含对象的int数组。这些对象增加了很少(8或12)字节的开销,这样底层的int就不会被严格打包。

因此它们跨越了不同数量的缓存线,在这里, 虚假共享 起作用。由于缓存线通常是64字节,所以new AtomicIntegerArray(10)的全部数据都符合它(除非它开始对齐,然后使用两条缓存线)。这意味着错误共享的概率为100%,也就是说,它就像单个变量满足所有线程一样。

使用AtomicBoolean[]的开销,我们可以得到大约160个字节,而不是40个字节,因此更少的错误共享。

我猜格雷的基准有相当多的开销(%操作和条件),实际的速度差异会更大。

这并不意味着AtomicIntegerArray是坏的。只是如果真的激烈竞争的话,就不应该这样使用。简单的解决方案是分配一个大得多的数组,并且只使用每16个元素,有效地将错误共享减少到零。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22236928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档