java单例1001无标题_#CHALLENGE_1001 - 单例模式

best practice: Sinigleton w/ enum

public enum Singleton {

INSTANCE;

public void whateverMethod() {

}

}

pro:

concise, and thread-safe.

enum is singleton by design. All the enum values are initialized only once when class loaded.

enum 支持反序列化机制,无需实现 Serializable 接口和重写 readResolve() 方法,即可避免反序列化中对单例模式的破坏。

enum can’t be initialized via reflection. 试图通过反射方式得到单例对象,会报错:java.lang.IllegalArgumentException: Cannot reflectively create enum objects.

con: none.

Traditional Methods of Making Singletons:

2.1 : Eagerly Initialized Singleton

public class EagerSingleton {

/** private constructor to prevent others from instantiating this class */

private EagerSingleton() {}

/** Create an instance of the class at the time of class loading */

private static final EagerSingleton instance = new EagerSingleton();

/** Provide a global point of access to the instance */

public static EagerSingleton getInstance() {

return instance;

}

}

pro: thread-safe.

con: the instance is created irrespective of whether it is accessed or not. This is fine if the object is simple and does not hold any system resources. But can have performance implications if it allocates a large amount of system resources and remains unused.

2.2 : Eagerly Initialized Static Block Singleton

public class EagerStaticBlockSingleton {

private static final EagerStaticBlockSingleton instance;

/** Don't let anyone else instantiate this class */

private EagerStaticBlockSingleton() {}

/** Create the one-and-only instance in a static block */

static {

instance = new EagerStaticBlockSingleton();

}

/** Provide a public method to get the instance that we created */

public static EagerStaticBlockSingleton getInstance() {

return instance;

}

}

pro:thread-safe.

con:the instance is created whether or not it is needed by the application.

2.3 : Lazily Initialized Singleton

public class LazySingleton {

private static LazySingleton instance;

/** Don't let anyone else instantiate this class */

private LazySingleton() {}

/** Lazily create the instance when it is accessed for the first time */

public static synchronized LazySingleton getInstance() {

if(instance == null) {

instance = new LazySingleton();

}

return instance;

}

}

pro:The synchronized keyword ensures thread-safety.

con:The synchronized solution is kinda inefficient.

2.4 : Lazily Initialized Double-Checked Locking Singleton

public class LazyDoubleCheckedLockingSingleton {

private static volatile LazyDoubleCheckedLockingSingleton instance;

/** private constructor to prevent others from instantiating this class */

private LazyDoubleCheckedLockingSingleton() {}

/** Lazily initialize the singleton in a synchronized block */

public static LazyDoubleCheckedLockingSingleton getInstance() {

if(instance == null) {

synchronized (LazyDoubleCheckedLockingSingleton.class) {

// double-check

if(instance == null) {

instance = new LazyDoubleCheckedLockingSingleton();

}

}

}

return instance;

}

}

pro:the use of volatile keyword is necessary here to prevent compilers from doing their own optimizations (like instruction reordering). and it's thread-safe.

con:not very efficient.

2.5 Lazily Initialized Inner Class Singleton

public class LazyInnerClassSingleton {

/** private constructor to prevent others from instantiating this class */

private LazyInnerClassSingleton() {}

/** This inner class is loaded only after getInstance() is called for the first time. */

private static class SingletonHelper {

private static final LazyInnerClassSingleton INSTANCE = new LazyInnerClassSingleton();

}

public static LazyInnerClassSingleton getInstance() {

return SingletonHelper.INSTANCE;

}

}

pro: most efficient due to the reason that the inner class is not loaded until the getInstance() method is invoked for the first time. This solution is thread-safe and doesn’t require any other synchronization.

con: none.

Conclusion:

The examples above are several thread-safe ways of implementing the singleton design pattern. (who would want thread-unsafe solutions?)

Last but not the least, 简单描述一下单例模式的应用场景:

单例模式能保证在一个JVM中,对象只有一个实例存在。正是由于这个特点,单例对象通常作为程序中的存放配置信息的载体,因为它能保证其他对象读到一致的信息。例如在某个服务器程序中,该服务器的配置信息可能存放在数据库或文件中,这些配置数据由某个单例对象统一读取,服务进程中的其他对象如果要获取这些配置信息,只需访问该单例对象即可。这种方式极大地简化了在复杂环境下,尤其是多线程环境下的配置管理,但是随着应用场景的不同,也可能带来一些同步问题。我们具体问题具体分析吧。

EOF

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值