Effective Java学习笔记之三:使用私有构造器或枚举实现单例

  • 解释

单例模式指一个类在它的生命周期内只会存在一个实例,通常被用于无状态的类。实现单例模式有3种方法(其实有更多种,Effective Java列出3种):

1、public final static成员变量

public static final Rule3 INSTANCE= new Rule3();
Private Rule3() { }

2、静态工厂

private static final Rule3 INSTANCE = new Rule3();
private Rule3() { }
public static Rule3 getInstance() { return INSTANCE; }

3、枚举

public enum Rule3{
INSTANCE;
private Rule3() {
//do something
}
}
  • 优点1:简单

3种方法都非常简单、容易实现。

  • 优点2:安全

都是饿汉式单例模式,能够保证线程安全。尤其枚举方式实现的单例,无偿地提供了序列化机制,绝对防止多次实例化,即使是在面对复杂的序列化或者反射攻击的时候。

缺点1:不支持懒加载

3种方法都是先进行实例化,无论你是否使用到这个类。当然,这点缺点影响不大,如果是实例化带来资源消费非常大的场景,可能要考虑懒汉式单例模式。

  • 带volatile双重判空懒汉式
//volatile防止指令重排
private static volatile Rule3 instance;
private Rule3() {}
public static Rule3 getInstance() {
//当实例不为空时,线程不会进入同步块
if (instance == null) {
synchronized (Rule3.class) {
//避免第2个线程进入同步块时进行实例化
if (instance == null) {
instance = new Rule3();
}
}
}
return instance;
}
  • 最佳实践

使用Spring框架时,默认bean实例化是注册登记式单例,每使用一次,都往一个固定的容器中去注册并且将使用过的对象进行缓存,下次去取对象的时候,就直接从缓存中取值,以保证每次获取的都是同一个对象,不需要自己去实现单例了。非Spring场景下,可以考虑带volatile双重判空懒汉式或者枚举方式实现单例。

Effective Java学习笔记之三:使用私有构造器或枚举实现单例

专业从事软件研发工作多年,在软件设计、开发、测试、研发管理等领域里经验丰富,感兴趣的朋友可以关注我的头条号,相信一定会有所收获。如果有软件研发方面的问题,可以咨询我。谢谢!


分享到:


相關文章: