编程语言
首页 > 编程语言> > java – 有没有理由不总是使用AtomicInteger作为数据成员?

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