單例模式6種實現及利弊分析
目錄
單例模式6種實現及利弊分析
單例模式三要素
- 私有的構造方法;
- 指向自己實例的私有靜態引用;
- 以自己實例為返回值的靜態的公有方法
1.餓漢式
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){};
public static Singleton getSingleton(){
return singleton;
}
}
優點:執行緒安全,在類載入完成時就完成了初始化,調用效率高
缺點:類載入較慢,無法達到懶載入的效果
2.懶漢式(非執行緒安全)
public class Singleton{
private static Singleton singleton;
private Singleton(){};
public static Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
優點:節約資源,實現懶載入
缺點:非執行緒安全,獲取對象需要實例化,調用效率低
3.懶漢式(synchronized)
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.懶漢式(靜態內部類)
public class Singleton{
private static class Holder{
private static Singleton singleton = new Singleton();
}
private Singleton(){};
public static Singleton getSingleton(){
return Holder.singleton;
}
}
優點:執行緒安全,實現懶載入
缺點:暫無
5.懶漢式(雙重鎖DCL)
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)
public class Singleton {
private static volatile Singleton singleton;
private static ThreadLocal<Singleton> 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;
}
}
優點:也相當於實現了雙重檢查,執行緒安全
缺點:效率不及傳統雙重檢查