Java JVM如何确保使用enum实现的线程安全单例?

Java JVM如何确保使用enum实现的线程安全单例?,java,enums,jvm,Java,Enums,Jvm,正如Josh Bloch所说,Enum是实现单例模式的最佳方式 JavaEnum自己负责序列化和线程安全。但我不明白怎么做 有人能解释一下吗 我看了看,又看了看 第二个链接提供了大量有关enum能够序列化的详细信息,但我没有得到关于线程安全的充分解释 enum中声明的方法是否也是线程安全的,或者需要特别注意吗?static初始值设定项块是使用JVM内部锁的单线程的。i、 e.它不像其他锁那样出现在jstack跟踪中。在初始化类之前,没有其他线程可以访问该类的任何内容。这适用于所有类,而不仅仅是e

正如Josh Bloch所说,Enum是实现单例模式的最佳方式

JavaEnum自己负责序列化和线程安全。但我不明白怎么做

有人能解释一下吗

我看了看,又看了看

第二个链接提供了大量有关enum能够序列化的详细信息,但我没有得到关于线程安全的充分解释


enum中声明的方法是否也是线程安全的,或者需要特别注意吗?

static
初始值设定项块是使用JVM内部锁的单线程的。i、 e.它不像其他锁那样出现在
jstack
跟踪中。在初始化类之前,没有其他线程可以访问该类的任何内容。这适用于所有类,而不仅仅是
enum

enum
在编译器生成的静态初始值设定项块中初始化

enum中声明的方法是线程安全的还是需要特别注意

同样,
enum
与常规类类似。只有标记为
synchronized
的方法才会同步。注意:仅仅添加synchronized并不能保证线程安全

虽然
enum
是有效的
static final
实例,但您可以修改它们的字段,即默认情况下,枚举上的字段不是
final
。此外,您还可以使用反射和Unsafe.allocateInstance来修改枚举,从而破坏类的内部结构。一般来说,这不是一个好主意

对于每个名为n的已声明枚举常量,枚举类型都有一个隐式声明的公共静态最终字段,名为E类型的n。在枚举类型中显式声明任何静态字段之前,这些字段被视为按照与相应枚举常量相同的顺序声明


枚举是静态实例,它们将在类加载时初始化。一旦它们初始化,您就无法更改/修改它们。所以它是线程安全的。创建枚举实例后,不会对其进行任何修改


但是,添加到枚举类中的方法没有任何线程安全保证,除非您显式声明它。

您能给我指一个资源,它说“枚举是在编译器生成的静态初始化器块中初始化的。”?我的意思是尝试寻找,但可以得到一个。作为后续问题,所有这些都可以在非枚举类中完成,并使其像枚举一样健壮吗?@我认为是的,可悲。但正如这里所解释的,你必须付出很大的努力:@Sam这么说。它实际上不是一个块,而是
静态final
字段,每个
枚举
常量都有相应的初始化表达式(这几乎是等效的)。@SotiriosDelimanolis如果我错了,请纠正我。因此,使其成为静态final会使枚举线程安全,对吗?