设计模式之单例模式

1.单例模式的定义:

单例模式(Singleton Pattern)属于创建型模式,它是Java中最简单的设计模式之一。单例模式确保一个类只有一个实例,并提供一个全局访问点。

2.单例模式的使用场景:

单例模式的意图是保证一个类仅有一个实例,并且提供一个访问它的全局访问点。它主要解决一个全局使用的类被频繁地创建与销毁的问题。因此当我们想控制实例数目,节省系统资源的时候就可以使用单例模式。

① 资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。

② 控制资源的情况下,方便资源之间的互相通信。如线程池等。

3.单例模式的具体实现方式:

单例模式要素:① 私有构造方法 ② 私有静态变量指向自己的实例 ③ 以该静态变量为返回值的公共静态方法

实现方式一:使用枚举(推荐)

在Java中枚举本身就是一种单例模式,并且枚举类型的创建是线程安全的。使用枚举方式实现单例模式,写法简单,调用效率高,同时可以天然的防止反射和反序列化调用。缺点就是不具备延迟加载。

1
2
3
4
public enum SingletonEnum {
INSTANCE;
public void doSomeThing() {}
}
实现方式二:双重检查懒汉模式(推荐)

双重检查模式本质上是线程安全的懒汉模式,也称作DCL(Double Check Lock)单例模式。该方式的亮点主要在于进行了双重判断和volatile关键字的使用。它具备延迟加载、效率较高的优点。

第一层判断主要是为了避免不必要的同步操作,增加访问效率。第二层判断是为了保证在实例不存在的情况下再去创建实例。

使用volatile关键字主要是为了禁止创建实例的指令重排序,确保实例不为null时,是完全创建成功的。

创建对象主要分为三个步骤:① 给实例分配内存空间 ② 调用对象构造函数 ③ 将引用变量指向实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Singleton {
private static volatile Singleton instance;
private Singleton () {}

public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
实现方式三:饿汉模式
1
2
3
4
5
6
7
8
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}

public static Singleton getInstance() {
return INSTANCE;
}
}
实现方式四:静态内部类
1
2
3
4
5
6
7
8
9
10
11
public class Singleton {
private Singleton() {}

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

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

4.单例模式的主要应用场合:

① 在Spring的IOC容器中,创建的Bean实例默认都是单例的。

② Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。

③ 网站的计数器,一般也是采用单例模式实现,否则难以同步。

④ 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。

⑤ 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,所以用单例模式来维护,就可以大大降低这种损耗。

⑥ 多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。

0%