有没有理由不总是使用AtomicInteger作为数据成员? [英] Is there any justification not to ALWAYS use AtomicInteger as data members?
问题描述
在像Android这样的多线程环境中,一个简单的 int
变量可能被多个线程操纵,在这种情况下仍然有理由使用 int
作为数据成员?
In a multi-threaded environment like Android, where a simple int
variable may be manipulated by multiple threads, are there circumstances in which it is still justified to use an int
as a data member?
一个 int
作为局部变量,限于具有独占访问权限的方法的范围(因此开始和完成修改它总是在同一个线程中),在性能方面做得非常完美。
An int
as a local variable, limited to the scope of the method that has exclusive access to it (and thus start & finish of modifying it is always in the same thread), makes perfect sense performance-wise.
但作为数据成员,即使被访问者包装,也会遇到众所周知的并发交错修改问题。
But as a data member, even if wrapped by an accessor, it can run into the well known concurrent interleaved modification problem.
所以看起来像要安全地玩,可以全面使用 AtomicInteger
。但这看起来非常低效。
So it looks like to "play it safe" one could just use AtomicInteger
across the board. But this seems awfully inefficient.
你能带一个线程安全 int
数据成员用法的例子吗?
Can you bring an example of thread-safe int
data member usage?
推荐答案
有没有理由不总是使用AtomicInteger作为数据成员?
Is there any justification not to ALWAYS use AtomicInteger as data members?
是的,有充分的理由不总是使用 AtomicInteger
。 AtomicInteger
因为 volatile
构造而不是本地<至少一个数量级(可能更多) code> int 和另一个不安全
构造用于设置/获取基础 int
价值。 volatile
表示您在访问 AtomicInteger
的每个时间内穿过内存屏障,这会导致缓存内存冲洗在有问题的处理器上。
Yes, there are good reasons to not always use AtomicInteger
. AtomicInteger
can be at at least an order of magnitude slower (probably more) because of the volatile
construct than a local int
and the other Unsafe
constructs being used to set/get the underlying int
value. volatile
means that you cross a memory barrier every time you access an AtomicInteger
which causes a cache memory flush on the processor in question.
另外,只是因为你已将所有字段设为 AtomicInteger
在访问多个字段时,不会保护您免受竞争条件的影响。没有什么可以替代做出关于何时使用 volatile
, synchronized
和的明确决定> Atomic *
类。
Also, just because you have made all of your fields to be AtomicInteger
does not protect you against race conditions when multiple fields are being accessed. There is just no substitute for making good decisions about when to use volatile
, synchronized
, and the Atomic*
classes.
例如,如果您想在一个线程中以可靠的方式访问类中的两个字段程序,然后你会做类似的事情:
For example, if you had two fields in a class that you wanted to access in a reliable manner in a thread program, then you'd do something like:
synchronized (someObject) {
someObject.count++;
someObject.total += someObject.count;
}
如果这两个成员都 AtomicInteger
然后你将访问 volatile
两次,因此跨越2个内存屏障而不是1个。此外,分配比不安全快
AtomicInteger
内的操作。此外,由于两个操作的数据竞争条件(与上面的 synchronized
块相反),您可能无法获得 total <的正确值/ code>。
If both of those members with AtomicInteger
then you'd be accessing volatile
twice so crossing 2 memory barriers instead of just 1. Also, the assignments are faster than the Unsafe
operations inside of AtomicInteger
. Also, because of the data race conditions with the two operations (as opposed to the synchronized
blocks above) you might not get the right values for total
.
你能带一个线程安全的int数据成员用法的例子吗?
Can you bring an example of thread-safe int data member usage?
除了使 final
之外,没有线程安全的机制 int
数据成员除了标记 volatile
或使用 AtomicInteger
。没有神奇的方法可以在所有字段上绘制线程安全性。如果有,那么线程编程将很容易。挑战在于找到适合放置 synchronized
块的地方。要查找应使用 volatile
标记的正确字段。找到合适的地方 AtomicInteger
和朋友。
Aside from making it final
, there is no mechanism for a thread-safe int
data member except for marking it volatile
or using AtomicInteger
. There is no magic way to paint thread-safety on all of your fields. If there was then thread programming would be easy. The challenge is to find the right places to put your synchronized
blocks. To find the right fields that should be marked with volatile
. To find the proper places to use AtomicInteger
and friends.
这篇关于有没有理由不总是使用AtomicInteger作为数据成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!