单例模式

设计模式/创建型设计模式

简述

采用一定的方法保证在整个软件系统中,一个类只能存在一个对象实例,
并且该类只提供一个访问其对象实例的方法(静态方法)。

⚠️注意

  • 单例类只能有一个实例
  • 单例类必须自己创建自己唯一实例
  • 单例类必须给所有其他对象提供这一实例
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

@Slf4j
public class HungryCat extends Cat {
private static HungryCat hungryCat = new HungryCat();

private HungryCat() {
log.debug("饥饿的猫猫");
}

/**
* 1.饿汉模式(静态常量)
* 优缺点:
* 优点:写法简单,就是在类加载时候直接完成实例化,避免线程同步问题
* 缺点:没有达到懒加载的效果,如果该类从始至终都没有使用,会造成内存浪费
*/
public static HungryCat getInstance() {
return hungryCat;
}
}

@Slf4j
public class LazyCat extends Cat {
private static LazyCat lazyCat;

private LazyCat() {
log.debug("懒懒的猫猫");
}

/**
* 2.懒汉单例模式(非同步)
* 优缺点:
* 优点:有懒加载效果
* 缺点:线程不安全,只适合单线程使用
*/
public static LazyCat getInstance() {
if (lazyCat == null) {
lazyCat = new LazyCat();
}
return lazyCat;
}

/**
* 方法1
* 使用synchronized将整个方法同步
* 但同步整个方法在高并发的情况下会造成阻塞效率低下
* 不推荐使用
*/
public static synchronized LazyCat getSyncInstance() {
if (lazyCat == null) {
lazyCat = new LazyCat();
}
return lazyCat;
}

/**
* 方法2
* 使用synchronized同步该单例的代码块;但该方法不能完全实现同步,可能会产生多个实例;
* 例如:在第一次创建时多个线程同时进入if(lazySingleton == null) 则会产生多个实例
* 不推荐使用
*/
public static LazyCat getSyncSuperiorInstance() {
if (lazyCat == null) {
synchronized (LazyCat.class) {
lazyCat = new LazyCat();
}
}
return lazyCat;
}

/**
* 方法3
* 双重检查法,同步代码块中再次检查一次是否w为null解决了上述问题 * 推荐使用
*/
public static LazyCat getSyncAdvanceInstance() {
if (lazyCat == null) {
synchronized (LazyCat.class) {
if (lazyCat == null) {
lazyCat = new LazyCat();
}
}
}
return lazyCat;
}
}

@Slf4j
public class InnerClassCat extends Cat {
private InnerClassCat() {
log.debug(“内部的猫猫”);
}

/**
* 4.内部类模式
* 优点:采用了类加载机制来保证初始化实例只有一个线程,懒加载,效率高
* 推荐使用
*/
public static InnerClassCat getInstance() {
return Inner.innerClassCat;
}

private static class Inner {
private static InnerClassCat innerClassCat = new InnerClassCat();
}
}

// 5.枚举模式
enum CarBean {
carBean;
}