面試被虐系列_設計模式篇_單例模式
阿新 • • 發佈:2019-02-10
題目:請手寫程式碼實現單例模式,要求多種實現方式,並闡述原理。
思考:
單例模式是日常開發中一種非常常見的設計模式。在所有需要資源複用,或者保持引用例項唯一性的場景下,該設計模式都可以被運用來完成具體的實現。在ASP.NET中的HttpApplication,JAVA執行緒池,Winform的窗體等,都運用了單例模式。
單例模式在實現單例的過程中,本質上都是對以下幾個問題的合理處理:保持單例唯一,控制獲取例項的方法使用,保證執行緒安全,效能的瓶頸。在其中的一些點上,C#和JAVA的處理機制有些許不同,這裡分別用兩種語言進行實現。
本人的實現方式參考了一些前輩的博文,同時自己也整理了一下。僅僅作為參考,隨時歡迎交流。
C#單例模式的實現
//1.經典模式:直接通過內部成員物件實現。問題:執行緒不安全,多執行緒併發的場景下無法保證資料可靠性。
public class SingletonDemo1
{
private static SingletonDemo1 singleton;
private SingletonDemo1()
{
}
public static SingletonDemo1 getInstance()
{
if (singleton == null )
{
singleton = new SingletonDemo1();
}
return singleton;
}
}
//2.懶漢模式:通過加鎖實現執行緒安全。問題:該方法需要手動加鎖,編碼繁瑣容易出錯,且在併發的過程中執行緒是阻塞的,效能很差。
public class SingletonDemo2
{
private volatile static SingletonDemo2 singleton = null;
private static readonly object lockHelper = new object();
private SingletonDemo2() { }
public static SingletonDemo2 CreateInstance()
{
if (singleton == null)
{
lock (lockHelper)
{
if (singleton == null)
singleton = new SingletonDemo2();
}
}
return singleton;
}
}
//3.餓漢模式:通過在類內部主動建立例項實現。
public class SingletonDemo3
{
private static readonly SingletonDemo3 singleton
= new SingletonDemo3();
private SingletonDemo3() { }
public static SingletonDemo3 CreateInstance()
{
return singleton;
}
}
//4.直接通過readonly修飾的成員獲取例項。本質上和第三種方法是一樣的,但是寫起來很簡潔。
public class SingletonDemo4
{
private SingletonDemo4() { }
public static readonly SingletonDemo4 singleton
= new SingletonDemo4();
}
JAVA單例模式的實現
//1.懶漢模式,執行緒不安全。
public class Singleton1 {
private static Singleton1 instance;
private Singleton1 (){}
public static Singleton1 getInstance() {
if (instance == null) {
instance = new Singleton1();
}
return instance;
}
}
//2.懶漢模式,加鎖實現執行緒安全。
public class Singleton2 {
private static Singleton2 instance;
private Singleton2 (){}
public static synchronized Singleton2 getInstance() {
if (instance == null) {
instance = new Singleton2();
}
return instance;
}
}
//3.餓漢模式
public class Singleton3 {
private static Singleton3 instance = new Singleton3();
private Singleton3 (){}
public static Singleton3 getInstance() {
return instance;
}
}
//4.餓漢模式,通過static關鍵字修飾,同樣是在初始化即完成例項化。
public class Singleton4 {
private Singleton4 instance = null;
static {
instance = new Singleton4();
}
private Singleton4 (){}
public static Singleton4 getInstance() {
return this.instance;
}
}
//5.通過內部靜態類
public class Singleton5 {
private static class SingletonHolder {
private static final Singleton5 INSTANCE = new Singleton5();
}
private Singleton5 (){}
public static final Singleton5 getInstance() {
return SingletonHolder.INSTANCE;
}
}
//6.通過列舉實現。
public enum Singleton6 {
INSTANCE;
/***
Define other members of the enumerator.
***/
}
//7.雙重鎖校驗,此種方法類似c#中的lock方式,對判定和例項化物件的過程加鎖來實現。
public class Singleton7 {
private volatile static Singleton7 singleton;
private Singleton7 (){}
public static Singleton7 getSingleton() {
if (singleton == null) {
synchronized (Singleton7.class) {
if (singleton == null) {
singleton = new Singleton7();
}
}
}
return singleton;
}
}