根据Josh Bloch的Effective Java Enum是实现Singleton模式的最佳方式。
Java enum自己负责序列化和线程安全。但我不明白怎么做。
有人可以解释一下吗?
第二个链接提供了关于enum能够序列化的大量细节,但我没有得到关于线程安全的充分解释。
枚举中声明的方法也是线程安全的,还是需要特别注意?
答案 0 :(得分:4)
static
初始化程序块是使用JVM内部的Lock的单线程。即它不像其他锁一样出现在jstack
跟踪中。在初始化之前,没有其他线程可以访问该类的任何内容。所有类都是如此,而不仅仅是enum
。
enum
在编译器生成的静态初始化程序块中初始化。
枚举中声明的方法也是线程安全的,还是需要特别注意?
同样,enum
就像常规课程一样。只有标记为synchronized
的方法才会同步。注意:只添加synchronized不会使其线程安全。 ;)
虽然enum
实际上是static final
个实例,但您可以修改其字段,即。默认情况下,枚举上的字段不是final
。您还可以使用反射和Unsafe.allocateInstance来修改类的内部结构来修改枚举。一般来说,这不是一个好主意。
对于名称为n的每个声明的枚举常量,枚举类型具有一个隐式声明的名为n的类型为E的公共静态最终字段。这些字段被认为是以与相应的枚举常量相同的顺序声明,在任何静态之前在枚举类型中显式声明的字段。
答案 1 :(得分:1)
枚举是静态实例,它们将在类加载时初始化。初始化后,您无法更改/修改它们。所以这是线程安全的。创建后不会修改Enum实例。
但是,除非明确声明,否则添加到枚举类的方法不带任何线程安全保证。