单例模式
# 1.简介
单例模式(Singleton Design Pattern)保证一个类只能有一个实例,并提供一个全局访问点。
必须要满足的三个条件:
- 单例类的构造函数必须是私有的,这样才能将类的创建权控制在类的内部,从而使得类的外部不能创建类的实例。
- 单例类通过一个私有的静态变量来存储其唯一实例。
- 单例类通过提供一个公开的静态方法,使得外部使用者可以访问类的唯一实例。
# 2.考虑的问题
- 创建单例对象时,是否线程安全。
- 单例对象的创建,是否延时加载。
- 获取单例对象时,是否需要加锁(锁会导致低性能)。
# 3. 代码实现
# 饿汉式
饿汉式的单例实现比较简单,其在类加载的时候,静态实例instance
就已创建并初始化好了。
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
2
3
4
5
6
7
8
9
饿汉式单例优缺点:
- 优点:
- 单例对象的创建是线程安全的;
- 获取单例对象时不需要加锁。
- 缺点:单例对象的创建,不是延时加载。
# 懒汉式
懒汉式为了支持延时加载,将对象的创建延迟到了获取对象的时候,但为了线程安全,不得不为获取对象的操作加锁,这就导致了低性能。
并且这把锁只有在第一次创建对象时有用,而之后每次获取对象,这把锁都是一个累赘(双重检测对此进行了改进)。
public class Singleton {
private static final Singleton instance;
private Singleton () {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
懒汉式单例优缺点:
- 优点:
- 对象的创建是线程安全的。
- 支持延时加载。
- 缺点:获取对象的操作被加上了锁,影响了并发度。
- 如果单例对象需要频繁使用,那这个缺点就是无法接受的。
- 如果单例对象不需要频繁使用,那这个缺点也无伤大雅。
# 双重检测
public class Singleton{
private static volatile Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance==null){
synchronized(this){
if(instance==null){
instance=new Singleton();
}
}
}
return instance;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
双重检测单例优点:
- 对象的创建是线程安全的。
- 支持延时加载。
- 获取对象时不需要加锁。
# 静态内部类
用静态内部类的方式实现单例类,利用了Java 静态内部类的特性:
- Java 加载外部类的时候,不会创建内部类的实例,只有在外部类使用到内部类的时候才会创建内部类实例。
public class Singleton {
private Singleton () {}
private static class SingletonInner {
private static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonInner.instance;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
- 对象的创建是线程安全的。
- 支持延时加载。
- 获取对象时不需要加锁。
# 枚举
用枚举来实现单例,是最简单的方式。这种实现方式通过 Java 枚举类型本身的特性,保证了实例创建的线程安全性和实例的唯一性。
public enum Singleton {
INSTANCE; // 该对象全局唯一
}
1
2
3
2
3
编辑 (opens new window)
上次更新: 2024/02/22, 14:03:19