单例设计模式

单例设计模式有很多种实现方式,但是不同的实现方式的效果自然也不同。但是绝大多数实现方式都要满足三要素:

  • 私有的构造方法。
  • 私有的静态的本类类型引用变量。
  • 公共的静态的获得实例的方法。

下面我就例举其中几个单例模式的实现方式。

懒汉式

话不多说,直接上代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public 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
2
3
4
5
6
7
8
9
10
11
12
13
public class SinglePattern2 {
//私有静态变量
private static SinglePattern2 single = new SinglePattern2();
//私有构造方法
private SinglePattern2() {
// TODO Auto-generated constructor stub
}
//公共静态的获取实例的方法
public static SinglePattern2 getInstance() {
return single;
}

}

顾名思义,饿汉模式,在类被加载的时候,实例就被创建出来了。
优点:多线程下是安全的
缺点:造成了资源的浪费

同步方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class SinglePattern3 {
//私有静态变量
private static SinglePattern3 single;
//私有构造方法
private SinglePattern3() {
// TODO Auto-generated constructor stub
}
//公共静态的获取实例的方法
public synchronized static SinglePattern3 getInstance() {
if (single == null)
single = new SinglePattern3();
return single;
}
}

在获得实例的方法上加上synchronized关键字,形成同步方法。
优点:多线程下是安全的。
缺点:同步方法,在多线程下,效率很低。

双重检测加锁法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class SinglePattern4 {
//私有静态变量
private static SinglePattern4 single;
//私有构造方法
private SinglePattern4() {
// TODO Auto-generated constructor stub
}
//公共静态的获取实例的方法
public static SinglePattern4 getInstance() {
//双重检测加锁法
if (single == null)
synchronized (SinglePattern4.class) {
if(single == null) {
single = new SinglePattern4();
}
}
return single;
}

}

两个非空的if判断加同步代码块约束构成了双重检测加锁法。
优点:多线程下安全。效率更高
缺点:使用了同步代码块,效率依旧受到了影响。
并且这种方法在多线程下并不一定完全安全,具体内容可以参考双重检查加锁法的安全性

静态内部类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class SinglePattern4 {
//私有静态变量
private static SinglePattern4 single;
//私有构造方法
private SinglePattern4() {
// TODO Auto-generated constructor stub
}
//私有静态内部类
private static class inner{
private static SinglePattern4 instance = new SinglePattern4();
}
//公共静态的获取实例的方法
public static SinglePattern4 getInstance() {
return inner.instance;
}

}

优点:兼顾了懒汉模式的内存优化(使用时才初始化)以及饿汉模式的安全性(不会被反射入侵)。
缺点:需要两个类去做到这一点,虽然不会创建静态内部类的对象,但是其 Class 对象还是会被创建,而且是属于永久带的对象。创建的单例,一旦在后期被销毁,不能重新创建。

-------------本文结束感谢您的阅读-------------