Skip to content

Commit fa8d126

Browse files
committed
auto commit
1 parent 621cbe8 commit fa8d126

File tree

1 file changed

+18
-18
lines changed

1 file changed

+18
-18
lines changed

notes/设计模式.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@
5858

5959
### 实现
6060

61-
**(一)懒汉式-线程不安全**
61+
(一)懒汉式-线程不安全
6262

6363
以下实现中,私有静态变量 uniqueInstance 被延迟化实例化,这样做的好处是,如果没有用到该类,那么就不会实例化 uniqueInstance,从而节约资源。
6464

65-
这个实现在多线程环境下是不安全的,如果多个线程能够同时进入 if (uniqueInstance == null) ,并且此时 uniqueInstance 为 null,那么多个线程会执行 uniqueInstance = new Singleton(); 语句,这将导致实例化多次 uniqueInstance。
65+
这个实现在多线程环境下是不安全的,如果多个线程能够同时进入 if (uniqueInstance == null) ,并且此时 uniqueInstance 为 null,那么多个线程会执行 uniqueInstance = new Singleton(); 语句,这将导致多次实例化 uniqueInstance。
6666

6767
```java
6868
public class Singleton {
@@ -81,7 +81,7 @@ public class Singleton {
8181
}
8282
```
8383

84-
**(二)懒汉式-线程安全**
84+
(二)懒汉式-线程安全
8585

8686
只需要对 getUniqueInstance() 方法加锁,那么在一个时间点只能有一个线程能够进入该方法,从而避免了对 uniqueInstance 进行多次实例化的问题。
8787

@@ -96,15 +96,15 @@ public static synchronized Singleton getUniqueInstance() {
9696
}
9797
```
9898

99-
**(三)饿汉式-线程安全**
99+
(三)饿汉式-线程安全
100100

101101
线程不安全问题主要是由于 uniqueInstance 被实例化了多次,如果 uniqueInstance 采用直接实例化的话,就不会被实例化多次,也就不会产生线程不安全问题。但是直接实例化的方式也丢失了延迟实例化带来的节约资源的优势。
102102

103103
```java
104104
private static Singleton uniqueInstance = new Singleton();
105105
```
106106

107-
**(四)双重校验锁-线程安全**
107+
(四)双重校验锁-线程安全
108108

109109
uniqueInstance 只需要被实例化一次,之后就可以直接使用了。加锁操作只需要对实例化那部分的代码进行。也就是说,只有当 uniqueInstance 没有被实例化时,才需要进行加锁。
110110

@@ -143,17 +143,17 @@ if (uniqueInstance == null) {
143143

144144
uniqueInstance 采用 volatile 关键字修饰也是很有必要的。uniqueInstance = new Singleton(); 这段代码其实是分为三步执行。
145145

146-
1. 分配内存空间
147-
2. 初始化对象
148-
3. 将 uniqueInstance 指向分配的内存地址
146+
1. 分配内存空间
147+
2. 初始化对象
148+
3. 将 uniqueInstance 指向分配的内存地址
149149

150150
但是由于 JVM 具有指令重排的特性,有可能执行顺序变为了 1>3>2,这在单线程情况下自然是没有问题。但如果是多线程下,有可能获得是一个还没有被初始化的实例,以致于程序出错。
151151

152152
使用 volatile 可以禁止 JVM 的指令重排,保证在多线程环境下也能正常运行。
153153

154-
**(五)枚举实现**
154+
(五)枚举实现
155155

156-
这是单例模式的最佳实践,它实现简单,并且在复杂的序列化或者反射攻击的时候,能够防止实例化多次。
156+
这是单例模式的最佳实践,它实现简单,并且在面对复杂的序列化或者反射攻击的时候,能够防止实例化多次。
157157

158158
```java
159159
public enum Singleton {
@@ -164,7 +164,7 @@ public enum Singleton {
164164
考虑以下单例模式的实现,该 Singleton 在每次序列化的时候都会创建一个新的实例,为了保证只创建一个实例,必须声明所有字段都是 transient,并且提供一个 readResolve() 方法。
165165

166166
```java
167-
public class Singleton implements Serializable{
167+
public class Singleton implements Serializable {
168168

169169
private static Singleton uniqueInstance;
170170

@@ -283,7 +283,7 @@ public class Client {
283283

284284
在简单工厂中,创建对象的是另一个类,而在工厂方法中,是由子类来创建对象。
285285

286-
下图中,Factory 有一个 doSomethind() 方法,这个方法需要用到一组产品对象,这组产品对象由 factoryMethod() 方法创建。该方法是抽象的,需要由子类去实现。
286+
下图中,Factory 有一个 doSomethind() 方法,这个方法需要用到一个产品对象,这个产品对象由 factoryMethod() 方法创建。该方法是抽象的,需要由子类去实现。
287287

288288
<div align="center"> <img src="../pics//1818e141-8700-4026-99f7-900a545875f5.png"/> </div><br>
289289

@@ -341,15 +341,15 @@ public class ConcreteFactory2 extends Factory {
341341

342342
### 类图
343343

344-
<div align="center"> <img src="../pics//8668a3e1-c9c7-4fcb-98b2-a96a5d841579.png"/> </div><br>
345-
346-
抽象工厂模式创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂模式只是用于创建一个对象,这和抽象工厂模式有很大不同。
344+
抽象工厂模式创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂方法模式只是用于创建一个对象,这和抽象工厂模式有很大不同。
347345

348-
抽象工厂模式用到了工厂模式来创建单一对象,AbstractFactory 中的 createProductA() 和 createProductB() 方法都是让子类来实现,这两个方法单独来看就是在创建一个对象,这符合工厂模式的定义
346+
抽象工厂模式用到了工厂方法模式来创建单一对象,AbstractFactory 中的 createProductA() 和 createProductB() 方法都是让子类来实现,这两个方法单独来看就是在创建一个对象,这符合工厂方法模式的定义
349347

350348
至于创建对象的家族这一概念是在 Client 体现,Client 要通过 AbstractFactory 同时调用两个方法来创建出两个对象,在这里这两个对象就有很大的相关性,Client 需要同时创建出这两个对象。
351349

352-
从高层次来看,抽象工厂使用了组合,即 Cilent 组合了 AbstractFactory,而工厂模式使用了继承。
350+
从高层次来看,抽象工厂使用了组合,即 Cilent 组合了 AbstractFactory,而工厂方法模式使用了继承。
351+
352+
<div align="center"> <img src="../pics//8668a3e1-c9c7-4fcb-98b2-a96a5d841579.png"/> </div><br>
353353

354354
### 代码实现
355355

@@ -584,7 +584,7 @@ abc
584584

585585
### 意图
586586

587-
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
587+
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链发送该请求,直到有一个对象处理它为止。
588588

589589
### 类图
590590

0 commit comments

Comments
 (0)