auto commit

This commit is contained in:
CyC2018 2018-03-03 10:58:53 +08:00
parent 28491d402e
commit 5cea88d6fa

View File

@ -739,9 +739,11 @@ MarinaraSauce
![](https://github.com/CyC2018/InterviewNotes/blob/master/pics//59aff6c1-8bc5-48e4-9e9c-082baeb2f274.jpg) ![](https://github.com/CyC2018/InterviewNotes/blob/master/pics//59aff6c1-8bc5-48e4-9e9c-082baeb2f274.jpg)
**3. 经典实现** **3. 懒汉式-线程不安全**
以下实现中,私有静态变量被延迟化实例化,这样做的好处是,如果没有用到该类,那么就不会创建该私有静态变量,从而节约资源。这个实现在多线程环境下是不安全的,因为多个线程能够同时进入 if(uniqueInstance == null) 内的语句块,那么就会多次实例化 uniqueInstance 私有静态变量。 以下实现中,私有静态变量被延迟化实例化,这样做的好处是,如果没有用到该类,那么就不会创建私有静态变量,从而节约资源。
这个实现在多线程环境下是不安全的,如果多个线程能够同时进入 if(uniqueInstance == null) 内的语句块,那么就会多次实例化 uniqueInstance 私有静态变量。
```java ```java
public class Singleton { public class Singleton {
@ -760,9 +762,9 @@ public class Singleton {
} }
``` ```
**4. 线程安全问题的解决方案一** **4. 懒汉式-线程安全**
只需要对 getUniqueInstance() 方法加锁,就能让该方法一次只能一个线程访问,从而避免了对 uniqueInstance 变量进行多次实例化的问题。但是这样有一个问题是一次只能一个线程进入,性能上会有一定的浪费 只需要对 getUniqueInstance() 方法加锁,那么在一个时间点只能有一个线程能够进入该方法,从而避免了对 uniqueInstance 进行多次实例化的问题。但是这样有一个问题,就是当一个线程进入该方法之后,其它线程视图进入该方法都必须等待,因此性能上有一定的损耗
```java ```java
public static synchronized Singleton getUniqueInstance() { public static synchronized Singleton getUniqueInstance() {
@ -773,17 +775,20 @@ public class Singleton {
} }
``` ```
**5. 线程安全问题的解决方案二** **5. 饿汉式-线程安全**
不用延迟实例化,采用直接实例化 线程不安全问题主要是由于静态实例变量被初始化了多次,那么静态实例变量采用直接实例化就可以解决问题。但是直接初始化的方法也丢失了延迟初始化节约资源的优势
```java ```java
private static Singleton uniqueInstance = new Singleton(); private static Singleton uniqueInstance = new Singleton();
``` ```
**6. 线程不安全问题的解决方案三** **6. 双重校验锁-线程安全**
因为 uniqueInstance 只需要被初始化一次,之后就可以直接使用了。加锁操作只需要对初始化那部分的代码进行,也就是说,只有当 uniqueInstance 没有被初始化时,才需要进行加锁。
双重校验锁先判断 uniqueInstance 是否已经被初始化了,如果没有被初始化,那么才对初始化的语句进行加锁。如果只做一次判断,那么多个线程还是有可能同时进入实例化语句块的,因此需要仅此第二次的判断。
考虑第一个解决方案,它是直接对 getUniqueInstance() 方法进行加锁,而实际上只需要对 uniqueInstance = new Singleton(); 这条语句加锁即可。使用两个条件语句来判断 uniqueInstance 是否已经实例化,如果没有实例化才需要加锁。
```java ```java
public class Singleton { public class Singleton {