設計模式 單例模式中的問題及優化方法

2021-08-20 03:21:53 字數 1596 閱讀 4780

單例模式是一種簡單常用的設計模式,但是越簡單的東西,其中包含的東西越不能忽略。

首先是執行緒不安全的單例模式:

public class unsafelazyinitialization 

//構造器私有化

private unsafelazyinitialization()

}

假設a執行緒執行**1的同時,b執行緒執行**2,執行緒a可能會看到instance引用的物件還沒有完成初始化,即執行緒不安全。

下面使用synchronized關鍵字使上面的**執行緒安全:

public class safelazyinitialization

private safelazyinitialization()

}

上面的**使執行緒安全了,但是導致了另乙個問題,由於getinstance()方法做了同步處理,synchronized將導致效能開銷;

如果getinstance()被多個執行緒頻繁呼叫,將會導致程式執行效能下降。

不過辦法總是比問題多的,下面將使用雙重檢查鎖定來解決這個問題:

public class doublecheckedlocking}}

return instance;

}//構造器私有化

public doublecheckedlocking()

}

以上的**是不是看起來完美無缺了呢,表面上看起來肯定使完美的,但這仍然是乙個錯誤的優化。

問題的根源:instance = new instance();

這一行**可以分為如下的三行**:

memory = allocate(); //1:分配物件的記憶體空間;

ctorinstance(memory);//2:初始化物件;

上面3行偽**中的2和3之間可能會被重排序,如下:

memory = allocate(); //1:分配物件的記憶體空間;

ctorinstance(memory);//2:初始化物件;

即當有執行緒在new instance()時,其他執行緒在判斷if(instance==null)時,可能判斷不為空,但是此時的物件還沒有完成初始化,最後導致問題。

囉嗦這麼半天,下面是最後的解決方案:

①基於volatile的解決方案:

/**

* 執行緒安全的懶漢單例模式

*/public class safedoublecheckedlocking}}

return instance;

}private safedoublecheckedlocking()

}

②基於類初始化的解決方案:

/**

* 餓漢單例模式

*/class instancefactory

public static instance getinstance()

private instancefactory()

}

以上就是單例模式的全部解析了,最後需要提醒的就是,單例的構造器一定要私有化!!!

設計優化之單例模式

寫乙個簡單的單例模式public class singleton private static singleton instance new singleton public static singleton getinstance 懶載入單例public class lazysingleton p...

設計優化之單例模式

寫乙個簡單的單例模式public class singleton private static singleton instance new singleton public static singleton getinstance 懶載入單例public class lazysingleton p...

php設計模式工廠模式及單例模式

工廠模式 class example else 單例設計模式程式 final class superman 召喚超人的唯一方法 return superman static function call return self self 除錯用方法 return string function get...