设计模式之单例模式

设计模式之单例模式

经典的延迟实例化(懒加载)的单例模式实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 经典的单例模式
* @author Mr.zxb
* @date 2020-08-15 21:17:31
*/
public class Singleton {
private static Singleton uniqueInstance;

private Singleton() {}

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

定义单例模式

单例模式确保一个类只有一个实例,并提供一个全局访问点。

多线程下,经典的实现就不一定是唯一实例,通过加锁保证唯一实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 多线程下安全的经典的单例模式
* @author Mr.zxb
* @date 2020-08-15 21:17:31
*/
public class Singleton {
private static Singleton uniqueInstance;

private Singleton() {}

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

不延迟实例化的单例模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 不延迟实例化的单例模式
* @author Mr.zxb
* @date 2020-08-15 21:17:31
*/
public class Singleton {
// JVM在加载这个类的时候,就会创建此实例
private static Singleton uniqueInstance = new Singleton();

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
21
/**
* 双重检查的单例模式,使用volatile保证多线程之间实例初始化后保持可见
* @author Mr.zxb
* @date 2020-08-15 21:17:31
*/
public class Singleton {
private volatile static Singleton uniqueInstance;

private Singleton() {}

public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}

总结

  • 单例模式确保程序中一个类最多只有一个实例
  • 单例模式也提供访问这个实例的全局点
  • 在Java中实现单例模式需要私有的构造器、一个静态方法和一个静态变量
  • 确定在性能和资源上的限制,然后小心地选择适当的方案来实现单例,以解决多线程的安全问题
  • 注意:如果使用多个类加载器,可能会导致单例失效而产生多个实例