java – 有没有理由不总是使用AtomicInteger作为数据成员?
作者:互联网
在像Android这样的多线程环境中,一个简单的int变量可能被多个线程操纵,在哪种情况下仍然有理由使用int作为数据成员?
作为局部变量的int,限于具有对它的独占访问权的方法的范围(因此开始和完成修改它总是在同一个线程中),在性能方面完全有意义.
但作为数据成员,即使由访问器包装,它也会遇到众所周知的并发交错修改问题.
所以看起来“玩得安全”可以全面使用AtomicInteger.但这看起来非常低效.
你能带一个线程安全的int数据成员用法的例子吗?
解决方法:
Is there any justification not to ALWAYS use AtomicInteger as data members?
是的,有充分的理由不总是使用AtomicInteger. AtomicInteger可以至少慢一个数量级(可能更多),因为volatile构造比一个局部int和其他Unsafe构造用于设置/获取底层int值. volatile表示每次访问AtomicInteger时都会跨越内存屏障,这会导致相关处理器上的缓存内存冲洗.
此外,仅仅因为您将所有字段设置为AtomicInteger并不能在访问多个字段时保护您免受竞争条件的影响.关于何时使用volatile,synchronized和Atomic *类做出正确的决定是没有替代品的.
例如,如果您希望在线程程序中以可靠的方式访问类中的两个字段,那么您将执行以下操作:
synchronized (someObject) {
someObject.count++;
someObject.total += someObject.count;
}
如果这两个成员都使用AtomicInteger,那么你将访问volatile两次,因此跨越2个内存屏障而不是1.此外,分配比AtomicInteger中的Unsafe操作更快.此外,由于两个操作的数据竞争条件(与上面的同步块相反),您可能无法获得正确的总值.
Can you bring an example of thread-safe int data member usage?
除了将其标记为volatile或使用AtomicInteger之外,除了使其成为最终之外,没有用于线程安全的int数据成员的机制.没有神奇的方法可以在所有字段上绘制线程安全性.如果有,那么线程编程将很容易.挑战在于找到放置同步块的正确位置.找到应标记为volatile的正确字段.找到合适的地方使用AtomicInteger和朋友.
标签:java,performance,multithreading,atomicity 来源: https://codeday.me/bug/20190723/1512582.html