我们可以在Java中使用Atomic Enum吗?

时间:2013-12-19 15:51:25

标签: java multithreading enums synchronized volatile

今天我看到了AtomicEnum的这个实用程序类,但我想知道是否有可能有原子枚举为什么它不包含在Java标准库中?事实上,我非常怀疑它是否真的是原子的,如果这个实用程序类有效。

AtomicEnum类是this

  1. 我如何检查它是否以原子方式执行操作?
  2. 是否有用于查看已编译代码的工具,并确保它仅用于完成所有操作 一机器指令?
  3. 是否可以从代码中发现它?
  4. 因此,如果这个Atomic枚举工作,我可以有一个属性AtomicEnum,它可以安全地使用它而没有volatile关键字和同步的getter和setter吗?

4 个答案:

答案 0 :(得分:17)

  

今天我看到了AtomicEnum的这个实用程序类,但我想知道是否有可能有原子枚举为什么它不包含在Java标准库中?

您链接到的AtomicEnum类只包含AtomicReference类,它为任何Object提供并发访问权。

如果您有多个线程正在获取并同时设置它,那么您真正需要volatile enumFieldvolatile关键字确保其他线程可以看到一个线程所做的更新。如果您需要执行AtomicReference类型的方法,则需要compareAndSet(...) - 如果该字段是特定值,则进行原子测试,然后才更新它。

  

如何检查它是否以原子方式执行操作?

AtomicReference是经过充分测试的java.util.concurrent类的一部分。

  

是否有工具可以查看已编译的代码,并确保它只在一台机器指令中完成所有操作?

这不应该是必要的。如果您想知道它在做什么,您可以查看AtomicReference来源。不幸的是,真正的神奇之处在于sun.misc.Unsafe原生代码。

  

是否可以从代码中发现它?

这不应该是必要的。

  

因此,如果这个Atomic枚举工作,我可以有一个属性AtomicEnum,它可以安全地使用它而没有volatile关键字和同步的getter和setter?

是的,AtomicReference包裹volatile V value,所以您不必这样做。

答案 1 :(得分:3)

这个AtomicEnum只是AtomicReference周围的一个瘦包装,这是有道理的,因为n enum值只是一个对象(引用)。

所以如果 AtomicReference正常工作(我认为我们可以假设),AtomicEnum也可以。

答案 2 :(得分:1)

对引用的访问是原子的,但对对象的访问不是。因此,引用值的更改将在所有线程中正确传播,但实际枚举对象的更改可能不会 实施例...

enum Weekdays {
    public int rank = 0;
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY;
}

案例1:

AtomicEnum<Weekdays> today = Weekdays.TUESDAY;

每个分享'今天'的帖子都会引用Weekdays.TUESDAY

案例2:

today.rank = 3;

无法保证每个帖子都有更新的排名。 (rank不是volatile。每个人都在缓存中维护对象的单独副本。)

所以引用访问是原子的,但是对象不是。
注:
1)原子访问并不意味着在一台机器指令中执行。但从逻辑上讲,它可以这样想。虽然它是不可分割的,但它可以包含几个指令 2)即使存在这样的工具,也很难测试它,因为更新过程几乎是不可预测的。因此可能出现误报结果。

希望这会有所帮助。

答案 3 :(得分:0)

我认为写任何这样的课没有意义。事实上,如果你正在写这样的课程,你需要重新思考课程的责任。 ENUM绝对是线程安全的,所以我不确定为什么有人需要AtominEnum,或者它只是某些类是Atomic并且还使用了一些枚举但是然后命名它AtomicEnum在设计或命名约定方面非常混乱。