Java 实现基于枚举的单例
J.Bloch在他的高效Java中建议我们使用基于枚举的单例实现。例如:Java 实现基于枚举的单例,java,enums,singleton,Java,Enums,Singleton,J.Bloch在他的高效Java中建议我们使用基于枚举的单例实现。例如: public enum Application { INSTANCE; //methods, fields } 在序列化的情况下,这个实现很好,因为枚举在默认情况下为我们提供了序列化功能(并且我们不必担心在反序列化对象时得到两个不同的实例) 我的问题是这个实现如何尊重多线程。如何使其线程安全?如果我们尝试从不同的线程访问它,我们可能会得到什么?安装实例的实际枚举行为。但是,您需要确保实例状态本身是线
public enum Application {
INSTANCE;
//methods, fields
}
在序列化的情况下,这个实现很好,因为枚举在默认情况下为我们提供了序列化功能(并且我们不必担心在反序列化对象时得到两个不同的实例)
我的问题是这个实现如何尊重多线程。如何使其线程安全?如果我们尝试从不同的线程访问它,我们可能会得到什么?安装实例的实际枚举行为。但是,您需要确保实例状态本身是线程安全的
与
应用程序
的字段和方法的交互是一个风险——使用谨慎的同步和锁定,或者使用纯粹的并发数据并仔细验证其他不一致性不会发生,这将是您的最佳选择。Singleton确保每个类装入器只有一个类实例
如果您的单例具有可变状态,则只需注意并发性。我的意思是,如果singleton保存了某种可变数据
在这种情况下,您应该使用某种同步锁定机制来防止并发修改状态和/或使用线程安全的数据结构。您可以像确保任何其他对象线程安全一样确保线程安全:通过确保正确同步对其状态的访问。如果它没有状态,它本质上是线程安全的。枚举的优点是它是线程安全的。另一个单例模式需要一个内部类来实现同样的功能,而且更为详细/神奇。因此,我仍然需要同步枚举的一些方法以确保线程安全?@St.Antario是的,因为枚举中的包装状态不是线程安全的“魔弹”。将其视为任何需要线程安全的类,但不要担心构造函数的线程安全(除了泄漏
this
)。