单例模式

1.定义

单例模式,属于创建类型的一种常用的设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例,保证一个类仅有一个实例,并提供一个访问它的全局访问点。

2.具体实现

2.1常用实现方式

饿汉式

1
2
3
4
5
6
7
public class Singleton {  
private static 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 static Singleton instance;
private Singleton (){}

public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

双重检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Singleton {
private static volatile Singleton instance;
public 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
9
10
11
public class Singleton {
public Singleton(){}

private static class Instace{
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance(){
return Instace.instance;
}
}

枚举

1
2
3
4
5
public enum Singleton {  
INSTANCE;
public void whateverMethod() {
}
}

​ 一般情况下,建议使用饿汉方式。只有在要明确实现 lazy loading 效果时,才会使用静态内部类方式。如果涉及到反序列化创建对象时,可以尝试使用枚举方式。如果有其他特殊的需求,可以考虑使用双检锁方式。

3.优点

  • 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
  • 避免对资源的多重占用(比如写文件操作)。

4.缺点

没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

5.使用场景

  • 要求生产唯一序列号。

  • WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。

  • 创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。