单例模式(Singleton Pattern)
半塘 2024/3/27 Java进阶
# 1、单例模式核心
一个类只能实例化一次,保证每次返回都是同一个实例对象。
- 私有化构造方法使得该类无法在外部通过new进行实例化
- 将类对象设置为static类型
- 饿汉模式加volatile防止重排序
- 加锁保证线程安全
# 2、实现方式
# 2.1、饿汉模式-线程安全
public class SingLetonMode {
// 静态对象
private static SingLetonMode singLetonMode = new SingLetonMode();
// 私有化构造方法使得该类无法在外部通过new进行实例化
private SingLetonMode() {}
// 饿汉模式,通过synchronized保证线程安全,并且初始化后就创建了
public static synchronized SingLetonMode getInstance(){
return singLetonMode;
}
// 对象实例方法
private void getName(){
System.out.println("饿汉模式");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 2.2、懒汉模式-线程不安全
public class SingLetonMode {
// 静态变量,volatile防止重排序
private static volatile SingLetonMode singLetonMode;
// 私有化构造方法使得该类无法在外部通过new进行实例化
private SingLetonMode() {}
// 懒汉模式,线程不安全
public static SingLetonMode getInstance(){
if(singLetonMode==null){
singLetonMode = new SingLetonMode();
}
return singLetonMode;
}
// 对象实例方法
public void getName(){
System.out.println("懒汉模式");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 2.3、懒汉模式-synchronized保证线程安全
public class SingLetonMode {
// 静态变量,volatile防止重排序
private static volatile SingLetonMode singLetonMode;
// 私有化构造方法使得该类无法在外部通过new进行实例化
private SingLetonMode() {}
// 懒汉模式,通过synchronized保证线程安全,但是效率慢
public static synchronized SingLetonMode getInstance(){
if(singLetonMode==null){
singLetonMode = new SingLetonMode();
}
return singLetonMode;
}
// 对象实例方法
private void getName(){
System.out.println("懒汉模式");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2.4、懒汉模式-双重检查锁保证线程安全
public class SingLetonMode {
// 静态变量,volatile防止重排序
private static volatile SingLetonMode singLetonMode;
// 私有化构造方法使得该类无法在外部通过new进行实例化
private SingLetonMode() {}
// 懒汉模式,通过双重检查锁保证线程安全,并保证效率(锁粒度小)
public static SingLetonMode getInstance(){
if (singLetonMode==null){
synchronized (SingLetonMode.class){
if(singLetonMode==null){
singLetonMode = new SingLetonMode();
}
}
}
return singLetonMode;
}
// 对象实例方法
private void getName(){
System.out.println("懒汉模式");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 2.5、懒汉模式-静态内部类方式
public class SingLetonMode {
private SingLetonMode() {}
// 当 SingLetonMode 类加载时,静态内部类 Singleton 没有被加载进内存,调用getInstance时才加载
private static class Singleton{
// 虚拟机提供了对线程安全的支持
private static final SingLetonMode singleton = new SingLetonMode();
}
// 初始化时,不进行调用,首次调用才初始化 Singleton.singleton
public static SingLetonMode getInstance(){
return Singleton.singleton;
}
// 对象实例方法
private void getName(){
System.out.println("懒汉模式");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2.6、枚举单例
能够防止反射攻击,具体可以看:枚举详解
public enum SingletonEnum {
INSTANCE;
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13