单例设计模式有很多种实现方式,但是不同的实现方式的效果自然也不同。但是绝大多数实现方式都要满足三要素:
- 私有的构造方法。
- 私有的静态的本类类型引用变量。
- 公共的静态的获得实例的方法。
下面我就例举其中几个单例模式的实现方式。
懒汉式
话不多说,直接上代码。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class SinglePattern1 {
//私有静态变量
private static SinglePattern1 single;
//私有构造方法
private SinglePattern1() {
// TODO Augenerated constructor stub
}
//公共静态的to-获取实例的方法
public static SinglePattern1 getInstance() {
if (single == null)
single = new SinglePattern1();
return single;
}
}
该方式在第一次需要用到该对象的时候,才new了一个对象出来,故称为懒汉。
优点:节省资源
缺点:多线程下单例容易被破坏
饿汉式
1 | public class SinglePattern2 { |
顾名思义,饿汉模式,在类被加载的时候,实例就被创建出来了。
优点:多线程下是安全的
缺点:造成了资源的浪费
同步方法
1 | public class SinglePattern3 { |
在获得实例的方法上加上synchronized关键字,形成同步方法。
优点:多线程下是安全的。
缺点:同步方法,在多线程下,效率很低。
双重检测加锁法
1 | public class SinglePattern4 { |
两个非空的if判断加同步代码块约束构成了双重检测加锁法。
优点:多线程下安全。效率更高
缺点:使用了同步代码块,效率依旧受到了影响。
并且这种方法在多线程下并不一定完全安全,具体内容可以参考双重检查加锁法的安全性。
静态内部类
1 | public class SinglePattern4 { |
优点:兼顾了懒汉模式的内存优化(使用时才初始化)以及饿汉模式的安全性(不会被反射入侵)。
缺点:需要两个类去做到这一点,虽然不会创建静态内部类的对象,但是其 Class 对象还是会被创建,而且是属于永久带的对象。创建的单例,一旦在后期被销毁,不能重新创建。