设计模式之单例模式

单例模式

定义

保证一个类只有一个实例, 并且提供一个访问它的全局访问点。

好处

  • 对于频繁使用而且不需要记录某些状态的对象,可以省略创建对象所花费的时间,这对于这些重量级对象而言,这是非常客观的一笔系统开销。
  • 由于new的次数减少,因为对系统内存的使用频率也会降低,这将减轻GC压力,缩短GC的停顿时间。

为什么不设置为静态变量

因为我们要保证资源的可用性,静态变量在程序加载了类的字节码之后,不需要创建任何实例对象就会被分配相应的空间,静态变量就可以被使用了。

如果对象一直没有被使用,这么对资源也会是一种消耗,此时我们就需要在使用时才创建对象,避免不必要的资源浪费。

单例模式的实现

两种构建方式:

  • 饿汉模式:指全局的单例实例在类装载时构建。
  • 懒汉模式:指全局的单例实例在第一次被使用时构建。

共同点:

  • 统一的private级别的构造函数
  • instance 成员变量和 uniqueInstance 方法必须是 static 的

饿汉模式(线程安全)

1
2
3
4
5
6
7
8
9
10
public class Singleton {
//在静态初始化器中创建单例实例,这段代码保证了线程安全
//volatile保证,当uniqueInstance变量被初始化成Singleton实例时,多个线程可以正确处理uniqueInstance变量
private volatile static Singleton uniqueInstance = new Singleton();
//Singleton类只有一个构造方法并且是被private修饰的,所以用户无法通过new方法创建该对象实例
private Singleton(){}
public static Singleton getInstance(){
return uniqueInstance;
}
}

懒汉模式(双重检查加锁版本)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Singleton {

//volatile保证,当uniqueInstance变量被初始化成Singleton实例时,多个线程可以正确处理uniqueInstance变量
private volatile static Singleton uniqueInstance;
private Singleton() {
}
public static Singleton getInstance() {
//检查实例,如果不存在,就进入同步代码块
if (uniqueInstance == null) {
//只有第一次才彻底执行这里的代码
synchronized(Singleton.class) {
//进入同步代码块后,再检查一次,如果仍是null,才创建实例
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}

参考

深入理解单例模式——只有一个实例

本文标题:设计模式之单例模式

文章作者:Enda Lin

发布时间:2019年06月11日 - 20:45

最后更新:2019年07月08日 - 09:15

原始链接:https://wt-git-repository.github.io/2019/06/11/设计模式之单例模式/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。