现实生活中使用和解释AtomicLongFieldUpdate类

时间:2013-06-21 16:00:16

标签: java multithreading atomic ocpjp

有人知道班级AtomicLongFieldUpdate的任何实际使用情况吗? 我已经阅读了描述,但我还没有完全理解它的含义。 为什么我想知道这个?好奇心和OCPJP准备。

提前致谢。

5 个答案:

答案 0 :(得分:5)

您可以考虑以下成本阶梯:

  • 普通long:便宜,但对多线程访问不安全
  • volatile long:更昂贵,更安全的多线程访问,无法进行原子操作
  • AtomicLong:最昂贵,可安全进行多线程访问,可能进行原子操作

(当我说“不安全”或“不可能”时,我的意思是“没有像同步这样的外部机制”。)

在需要多线程访问的情况下,但大多数操作都是简单的读取或写入,只需要几个原子操作,您可以创建一个AtomicLongFieldUpdate的静态实例,并在原子更新时使用它需要。然后,内存/运行时开销类似于简单的volatile变量,除了普通AtomicLong操作的顺序(或稍微贵一点)的原子操作。

这是nice little tutorial

答案 1 :(得分:2)

  

是否有人知道AtomicLongFieldUpdate课程的任何实际使用情况?

我自己从未使用过这个类,但是在我的工作区中使用它时,我看到了几个“真实”的实例:

  • com.google.common.util.concurrent.AtomicDouble使用它以原子方式修改其内部volatile long字段,该字段使用double存储来自Number.doubleToRawLongBits(...)的位。非常酷。

  • net.sf.ehcache.Element使用它以原子方式更新hitCount字段。

  

我已阅读说明,但我还没有完全理解它的含义。

它基本上提供与AtomicLong相同的功能,但是在另一个类的本地字段上。 AtomicLongFieldUpdate的内存负载小于AtomicLong,因为您为每个字段配置了一个更新实例,因此内存开销较低,但反射的CPU开销较大(尽管可能很小)。 p>

javadocs说:

  

此类设计用于原子数据结构,其中同一节点的多个字段独立地受原子更新。

当然,但我只使用多个Atomic*字段。我使用该类的唯一原因是,如果有一个我无法改变的现有类,我想以原子方式增加。

答案 2 :(得分:1)

您将使用例如AtomicLongFieldUpdater支持AtomicLong只是为了降低堆成本。在内部,两者在compareAndSet级别上的工作几乎完全相同,它们最后都使用sun.misc.Unsafe。

考虑你有一个初始化1000k次的某个类。使用AtomicLong,您可以创建1000k AtomicLongs。另一方面,使用AtomicLongFieldUpdater,您可以创建1个CONSTANT AtomicLongFieldUpdater和1000k长基元,这当然不需要太多堆空间。

答案 3 :(得分:0)

当然。我最近一直在阅读Alibaba 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");

如上定义,属性 recycleErrorCountconnectErrorCount 用于计算错误发生的次数。 相当多的 DataSource(持有上述属性的类)将在应用程序生命周期内创建,在这种情况下,使用 ALFU 明显比使用 AtomicLong 减少堆空间消耗。

答案 4 :(得分:-2)

Atomics通常用于并行编程。

在工作窃取模式下,它只支持异步,完成,异步同步,隔离和原子变量。

您可以将原子视为安全保护,免受数据争用以及并行编程中需要关注的其他问题的影响。