今天我看到了AtomicEnum的这个实用程序类,但我想知道是否有可能有原子枚举为什么它不包含在Java标准库中?事实上,我非常怀疑它是否真的是原子的,如果这个实用程序类有效。
AtomicEnum类是this
答案 0 :(得分:17)
今天我看到了AtomicEnum的这个实用程序类,但我想知道是否有可能有原子枚举为什么它不包含在Java标准库中?
您链接到的AtomicEnum
类只包含AtomicReference
类,它为任何Object
提供并发访问权。
如果您有多个线程正在获取并同时设置它,那么您真正需要volatile enumField
。 volatile
关键字确保其他线程可以看到一个线程所做的更新。如果您需要执行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在设计或命名约定方面非常混乱。