有人知道AtomicLongFieldUpdate类在现实生活中的任何用途吗?我已经阅读了描述,但我并没有完全理解它的含义。为什么我想知道这个?好奇心和 OCPJP 准备。
提前致谢。
有人知道AtomicLongFieldUpdate类在现实生活中的任何用途吗?我已经阅读了描述,但我并没有完全理解它的含义。为什么我想知道这个?好奇心和 OCPJP 准备。
提前致谢。
您可以考虑以下成本阶梯:
long
:便宜,但多线程访问不安全volatile long
:更昂贵,多线程访问安全,原子操作不可能AtomicLong
:最昂贵,多线程访问安全,可能的原子操作(当我说“不安全”或“不可能”时,我的意思当然是“没有像同步这样的外部机制”。)
在需要多线程访问的情况下,但大多数操作是简单的读取或写入,只需要少量原子操作,您可以创建一个静态实例AtomicLongFieldUpdate
并在需要原子更新时使用它。内存/运行时开销类似于一个简单的volatile
变量,除了原子操作的数量级(或略高于)普通AtomicLong
操作。
这是一个不错的小教程。
您使用例如 AtomicLongFieldUpdater 来支持 AtomicLong 的原因仅仅是为了降低堆成本。在内部,两者在 compareAndSet 级别上的工作几乎相同,最后都使用 sun.misc.Unsafe。
假设您有一个初始化 1000k 次的特定类。使用 AtomicLong,您将创建 1000k AtomicLong。另一方面,使用 AtomicLongFieldUpdater,您将创建 1 个 CONSTANT AtomicLongFieldUpdater 和 1000k 长的原语,这当然不需要那么多堆空间。
有人知道该
AtomicLongFieldUpdate
课程在现实生活中的任何用途吗?
我自己从来没有使用过这个类,但是在我的工作空间上使用 get 时,我看到了几个“现实生活”中的使用实例:
com.google.common.util.concurrent.AtomicDouble
使用它来原子地修改它们的内部volatile long
字段,该字段存储来自double
using的位Number.doubleToRawLongBits(...)
。很酷。
net.sf.ehcache.Element
使用它来自动更新hitCount
字段。
我已经阅读了描述,但我并没有完全理解它的含义。
AtomicLong
它基本上提供了与另一个类的本地字段相同的功能。的内存负载AtomicLongFieldUpdate
小于AtomicLong
您为每个字段配置一个更新实例的内存负载,因此内存开销较低,但来自反射的 CPU 开销更大(尽管可能很小)。
javadocs说:
此类设计用于原子数据结构,其中同一节点的多个字段独立地受到原子更新的影响。
当然可以,但是我只会使用多个Atomic*
字段。我使用该类的唯一原因是,如果有一个我无法更改的现有类,我想以原子方式递增。
当然。最近一直在看阿里巴巴的Druid。我发现AtomicLongFieldUpdater
在这个项目中被广泛使用。
// stats
private volatile long recycleErrorCount = 0L;
private volatile long connectErrorCount = 0L;
protected static final AtomicLongFieldUpdater<DruidDataSource> recycleErrorCountUpdater
= AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "recycleErrorCount");
protected static final AtomicLongFieldUpdater<DruidDataSource> connectErrorCountUpdater
= AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "connectErrorCount");
如上所述,属性recycleErrorCount
和connectErrorCount
用于计算错误发生次数。在应用程序生命周期中将创建相当多的DataSource
(包含上述属性的类),在这种情况下 usingALFU
明显比 using 减少堆空间消耗AtomicLong
。
原子通常用于并行编程。
在工作窃取模式下,它只支持 async、finish、forasync、isolated 和 atomic 变量。
您可以将原子视为对数据竞争和并行编程中需要关注的其他问题的安全保护。