单例模式的其他实现形式

1.饿汉模式

public class Singleton2 {

  private static final Singleton2 singleton = new Singleton2();

  private Singleton2() {}

  public static Singleton2 getInstance() {
       return singleton;
  }

}

在类加载时初始化单例,得益于类加载机制,饿汉模式线程安全,使用时没有延时。

坏处是有可能造成资源浪费(如果类加载后就一直不使用单例的话)。

值得注意的是,单线程环境下,饿汉与懒汉在性能上没有什么差别;但在多线程环境下,由于懒汉需要加锁,饿汉的性能反而更优。


2.用静态内部类实现的单例模式(Holder模式)

public class Singleton {

       private static LazyHolder {
               private static final Singleton INSTANCE = new Singleton();
       }

       private Singleton() {};

       public static Singleton getInstance() {
              return LazyHolder.INSTANCE;
       }

}

注意:
1.从外部无法访问静态内部类LazyHolder,只有当调用Singleton.getInstance方法的时候,才能得到单例对象INSTANCE。

2.INSTANCE对象初始化的时机并不是在单例类Singleton被加载的时候,而是在调用getInstance方法,使得静态内部类LazyHolder被加载的时候。因此这种实现方式是利用classloader的加载机制来实现懒加载,并保证构建单例的线程安全。

利用反射打破单例模式只能构建一个对象的约束

//获得构造器
Constructor con = Singleton.class.getDeclaredConstructor();

//设置为可访问
con.setAccessible(true);

//创建两个不同的对象
Singleton Singleton1 = (Singleton) con.newInstance();
Singleton Singleton2 = (Singleton) con.newInstance();


3.利用枚举防止反射的构建方式

public enum SingletonEnum {
       INSTANCE;
}

缺点:其单例对象是在枚举类被加载时完成初始化的。


枚举实现单例模式的本质:

public class Singleton4 extends Enum<Singleton4> {
  ...
  public static final Singleton4 SINGLETON = new Singleton4();
  ...
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------




几点补充:

1. volatile关键字不但可以防止指令重排,也可以保证线程访问的变量值是主内存中的最新值。有关volatile的详细原理,我在以后的漫画中会专门讲解。

2.使用枚举实现的单例模式,不但可以防止利用反射强行构建单例对象,而且可以在枚举类对象被反序列化的时候,保证反序列的返回结果是同一对象。

对于其他方式实现的单例模式,如果既想要做到可序列化,又想要反序列化为同一对象,则必须实现readResolve方法。


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

(来自程序员小灰)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值