單例模式6種實現及利弊分析
阿新 • • 發佈:2021-01-03
[TOC]
# 單例模式6種實現及利弊分析
單例模式三要素
- **私有的構造方法;**
- **指向自己例項的私有靜態引用;**
- **以自己例項為返回值的靜態的公有方法**
## **1.餓漢式**
```java
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){};
public static Singleton getSingleton(){
return singleton;
}
}
```
優點:執行緒安全,在類載入完成時就完成了初始化,呼叫效率高
缺點:類載入較慢,無法達到懶載入的效果
## **2.懶漢式(非執行緒安全)**
```java
public class Singleton{
private static Singleton singleton;
private Singleton(){};
public static Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
```
優點:節約資源,實現懶載入
缺點:非執行緒安全,獲取物件需要例項化,呼叫效率低
## **3.懶漢式(synchronized)**
```java
public class Singleton{
private static Singleton singleton;
private Singleton(){};
// 1.synchronized塊 實現執行緒安全
/*public static Singleton getSingleton(){
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
*/
// 2.synchronized方法 實現執行緒安全
public static synchronized Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
```
優點:執行緒安全,實現懶載入
缺點:獲取物件需要例項化,呼叫效率低
## **4.懶漢式(靜態內部類)**
```java
public class Singleton{
private static class Holder{
private static Singleton singleton = new Singleton();
}
private Singleton(){};
public static Singleton getSingleton(){
return Holder.singleton;
}
}
```
優點:執行緒安全,實現懶載入
缺點:暫無
## **5.懶漢式(雙重鎖DCL)**
```java
public class Singleton{
//volatile禁止指令重排序,避免DCL失效問題
private static volatile Singleton singleton;
private Singleton(){};
public static Singleton getSingleton(){
//避免重複的同步
if(singleton == null){
//如果未例項化,才進行加鎖
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
```
優點:執行緒安全,實現懶載入
缺點:暫無
## **6.懶漢式(ThreadLocal)**
```java
public class Singleton {
private static volatile Singleton singleton;
private static ThreadLocal threadLocal = new ThreadLocal<>();
private Singleton(){};
public static void createSingleton(){
synchronized (Singleton.class){
if (singleton == null){
singleton = new Singleton();
}
}
threadLocal.set(singleton);
}
public static Singleton getSingleton(){
if(threadLocal.get() == null){
createSingleton();
}
return singleton;
}
}
```
優點:也相當於實現了雙重檢查,執行緒安全
缺點:效率不及傳統雙