有没有理由不总是使用AtomicInteger作为数据成员? [英] Is there any justification not to ALWAYS use AtomicInteger as data members?

查看:148
本文介绍了有没有理由不总是使用AtomicInteger作为数据成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在像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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆