Skip to content

Commit

Permalink
auto commit
Browse files Browse the repository at this point in the history
  • Loading branch information
CyC2018 committed Feb 25, 2018
1 parent 1c69395 commit dd455bf
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 62 deletions.
60 changes: 1 addition & 59 deletions notes/剑指 offer 题解.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,65 +81,7 @@

## 2. 实现 Singleton

**经典实现**

以下实现中,私有静态变量被延迟化实例化,这样做的好处是,如果没有用到该类,那么就不会创建该私有静态变量,从而节约资源。这个实现在多线程环境下是不安全的,因为多个线程能够同时进入 if(uniqueInstance == null) 内的语句块,那么就会多次实例化 uniqueInstance 私有静态变量。

```java
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() {
}
public static Singleton getUniqueInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
```

**线程不安全问题的解决方案一**

只需要对 getUniqueInstance() 方法加锁,就能让该方法一次只能一个线程访问,从而避免了对 uniqueInstance 变量进行多次实例化的问题。但是这样有一个问题是一次只能一个线程进入,性能上会有一定的浪费。

```java
public static synchronized Singleton getUniqueInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
```
**线程不安全问题的解决方案二**

不用延迟实例化,采用直接实例化。

```java
private static Singleton uniqueInstance = new Singleton();
```

**线程不安全问题的解决方案三**

考虑第一个解决方案,它是直接对 getUniqueInstance() 方法进行加锁,而实际上只需要对 uniqueInstance = new Singleton(); 这条语句加锁即可。使用两个条件语句来判断 uniqueInstance 是否已经实例化,如果没有实例化才需要加锁。

```java
public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {
}
public static synchronized Singleton getUniqueInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
```
[单例模式](https://github.com/CyC2018/InterviewNotes/blob/master/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F.md#%E7%AC%AC-5-%E7%AB%A0-%E5%8D%95%E4%BB%B6%E6%A8%A1%E5%BC%8F)

## 3. 数组中重复的数字

Expand Down
8 changes: 5 additions & 3 deletions notes/设计模式.md
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,9 @@ CheesePizza

**3. 模式类图**

在简单工厂中,创建对象的是另一个类,而在工厂方法中,是由子类来创建对象。工厂方法常用在在每个子类都有自己的一组产品类。可以为每个子类创建单独的简单工厂,但是把简单工厂中创建对象的代码放到子类中来可以减少类的数目,因为子类不算是产品类,因此完全可以这么做。
在简单工厂中,创建对象的是另一个类,而在工厂方法中,是由子类来创建对象。下图中,Creator 有一个 anOperation() 方法,这个方法需要用到一组产品类,这组产品类由每个子类来创建。

可以为每个子类创建单独的简单工厂来创建每一个产品类,但是把简单工厂中创建对象的代码放到子类中来可以减少类的数目,因为子类不算是产品类,因此完全可以这么做。

![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/903093ec-acc8-4f9b-bf2c-b990b9a5390c.jpg)

Expand Down Expand Up @@ -599,7 +601,7 @@ ChicagoStyleCheesePizza is making..

**1. 设计原则**

**依赖倒置原则**:要依赖抽象,不要依赖具体类。听起来像是针对接口编程,不针对实现编程,但是这个原则说明了:不能让高层组件依赖底层组件,而且,不管高层或底层组件,两者都应该依赖于抽象。例如,下图中 PizzaStore 属于高层组件,但是它依赖于底层组件 Pizza 的具体类。如果依赖的是 Pizza 的抽象类,那么就可以不用关心 Pizza 的具体实现细节。
**依赖倒置原则**:要依赖抽象,不要依赖具体类。听起来像是针对接口编程,不针对实现编程,但是这个原则说明了:不能让高层组件依赖底层组件,而且,不管高层或底层组件,两者都应该依赖于抽象。例如,下图中 PizzaStore 属于高层组件,它依赖的是 Pizza 的抽象类,这样就可以不用关心 Pizza 的具体实现细节。

![](https://github.com/CyC2018/InterviewNotes/blob/master/pics/ddf72ca9-c0be-49d7-ab81-57a99a974c8e.jpg)

Expand Down Expand Up @@ -792,7 +794,7 @@ public class Singleton {
private Singleton() {
}

public static synchronized Singleton getUniqueInstance() {
public static Singleton getUniqueInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
Expand Down

0 comments on commit dd455bf

Please sign in to comment.