去面試(對,又去面試)
問:單例模式了解吧,來,拿紙和筆寫一下單例模式,
我心想,這TM不是瞧不起人嗎?我編程十年,能不知道單例模式,
答:(.net 平臺下)單例模式有兩種寫法:
第一種:饑餓模式,關鍵點,static readonly
public static readonly SingletonSimple Instance = new SingletonSimple();
第二種:懶加載模式,關鍵點,lock + 兩次判斷
static readonly object locker = new object(); static SingletonLazy singleton = null; public static SingletonLazy Instance { get { if (singleton == null) { lock (locker) { if (singleton == null) { singleton = new SingletonLazy(); } } } return singleton; } }
我再贈送你一種,第三種:通過IOC容器,注入單例,
問:這兩種方式(第一種和第二種)有什么不同嗎?(好戲開始)
答: 懶加載模式的單例是在類呼叫時進行創建,饑餓模式下的單例在程式啟動時創建(這里錯了),浪費資源,
似乎答案就是這樣,好些網文,博主也都是這么寫的,但大家都錯了,(輕信他人,不自己思考,這么基礎的東西居然沒搞明白)
反饋:錯,兩種方式并沒有本質的區別,都是在類呼叫的時候創建,
還沒有完,虐狗模式才剛剛開始,
問:說一下lock的原理
答:對代碼塊加鎖,加鎖的代碼只允許串行執行,防止并發沖突,lock本質上是通過 System.Threading.Monitor實作的,但lock使用比Monitor更簡單,可以自動釋放,
問:那Monitor是如何實作多個執行緒的阻塞呼叫的?一個執行緒執行完,是如何通知下一個執行緒執行的?有沒有自己實作過一個lock(不使用.net自帶的lock)?
答:......(完全一臉懵逼,根本不知道怎么回答)
問:IOC使用了什么設計模式,IOC是如何控制物件生命周期的?
答:......(還沒從剛才的窘迫中反應過來,更是不知道該說什么)
自己十年的作業經驗,就這么敗在了一個單例模式上,(T﹏T)
回家之后,自己做了實驗,證實兩種方式確實都是在類被呼叫的時候才會創建單例物件,
public static readonly 創建的單例
public class SingletonSimple
{
SingletonSimple()
{
Console.WriteLine($"Singleton Simple Create");
}
public static readonly SingletonSimple Instance = new SingletonSimple();
public void Work()
{
Console.WriteLine("Singleton Simple Work");
}
}
lock + 兩次判斷 創建的單例
public class SingletonLazy
{
SingletonLazy()
{
Console.WriteLine($"Singleton Lazy Create");
}
static readonly object locker = new object();
static SingletonLazy singleton = null;
public static SingletonLazy Instance
{
get
{
if (singleton == null)
{
lock (locker)
{
if (singleton == null)
{
singleton = new SingletonLazy();
}
}
}
return singleton;
}
}
public void Work()
{
Console.WriteLine("Singleton Lazy Work");
}
}
main函式
class Program
{
static void Main(string[] args)
{
Console.WriteLine("begin ...");
SingletonLazy.Instance.Work();
SingletonSimple.Instance.Work();
Console.WriteLine("end ...");
Console.Read();
}
}
輸出結果如下 :
begin ...
Singleton Lazy Create
Singleton Lazy Work
Singleton Simple Create
Singleton Simple Work
end ...
我們看,如果饑餓模式單例在程式啟動就自動加載的話,應該會先輸出“Singleton Simple Create”,但實際并不是這樣,并且我多次調整main函式中的單例呼叫順序,觀察結果,可以得出結論,兩種方式并沒有區別,都是在呼叫時加載的,
悔恨啊,居然栽在這么個小問題上,顏面掃地,
謹記:基礎原理,獨立思考,真的很重要,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/132195.html
標籤:.NET Core
上一篇:ArcGIS發布地圖服務
