淺談c#中使用lock的是與非(轉)
{
private static Singleton instance = null;
private static readonly object syncRoot = new object();
private Singleton()
{
}
public static Singleton GetInstance()
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
稍微瞭解設計模式基礎知識的人對上面的程式碼應該不會陌生。上次去面試,主考官就讓樓豬寫個單例。雖然平時已經很久沒有刻意去使用設計模式程式設計了,但是對於這個單例模式,咩哈哈,雖然大丈夫喜怒不形於色,但是nc樓豬當時那個意氣風發躊躇滿志運筆如飛鋒芒畢露啊,嘿嘿,中規中矩地交了如上答案。面試官看了一下肯定了兩句,話鋒一轉,問lock那裡的object例項可以直接用instance替代嗎?new一個object是否多餘,可否寫成下面的形式:
{
private static Singleton instance = null;
//private static readonly object syncRoot = new object();
private Singleton()
{
}
public static Singleton GetInstance()
{
if (instance == null)
{
lock (instance)//instance能替換syncRoot嗎?
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
雖然在這個問題前面,面試官問的一個資料庫設計和幾個c#的小問題(有一個題樓豬當時竟然嘴硬說那是“奇技淫巧”,好怕怕)很見知識深度和修養,樓豬已經小有提防,但是這個問題還是再次讓樓豬自亂陣腳。以前從來沒人問過樓豬這個問題,樓豬也沒主動想過它,腦袋裡一片白茫茫,剛想要鎮定下來,面試官又把相同問題問了一遍。不及細想,雖然不能確定,但是還是回答“應該可以...吧”(語氣助詞用得妙啊)。
肯定是對這個回答和回答的語氣不滿意,面試官又提醒問lock機制是什麼樣的,說說c#大概是怎麼實現lock的。樓豬語無倫次說lock本質上和作業系統相關,lock就是當前執行緒將資源獨佔其他執行緒不能訪問該鎖定資源云云,背書都不會背了嗎?無語了。面試官說回去自己試試吧。聽他的語氣,答案當然不言自明瞭,小心靈遭受重大挫折和打擊啊。
回來後,驗證了一下面試官的問題,程式執行到lock的時候,丟擲ArgumentNullException異常,“值不能為null”。為什麼lock一個指向null的引用例項不可以呢?
查了一下中文msdn:
lock 確保當一個執行緒位於程式碼的臨界區時,另一個執行緒不進入臨界區。如果其他執行緒試圖進入鎖定的程式碼,則它將一直等待(即被阻止),直到該物件被釋放。
老實說,直到看到最後一句“物件被釋放”才給了樓豬提示。某一物件可以指向null引用,但是null關鍵字是不需要釋放的吧?!是嗎?查了一下高人anytao的部落格,發現這篇認識全面的null給出了明確的答案。
接著樓豬又檢視了一下經常可以替代lock的Monitor類,赫然發現它的靜態方法Enter(object obj)有一個異常型別ArgumentNullException,早知道,也不會那麼狼狽啊。
2、lock的陷阱
除了msdn裡提到的lock需要注意的兩點外,園子裡早就有高手總結過了,可以參考這一篇。
3、最後自己總結得出的三個結論:
a、c#中null是不能lock的(null會分配記憶體嗎,會佔用系統資源嗎?和樓豬一起思考和探討吧)。
b、高手一出手,往往可以化腐朽為神奇。
c、對自己說:
加油。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-674405/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 突破還是災難? 淺談遊戲中的身份轉換與敘事遊戲
- 淺談 C# Assembly 與 IL (一):C# Assembly 與 ReflectionC#
- 淺談synchronized、Lock、ThreadLocal和semaphoresynchronizedthread
- 淺談在c#中使用Zlib壓縮與解壓的方法C#
- 淺談ActiveMQ與使用MQ
- 淺談聚簇索引與非聚簇索引索引
- [轉發]淺談我在職場中與人相處的技巧
- 淺談C#泛型C#泛型
- 淺談C#中重寫和隱藏的區別C#
- 淺談ASP.NET Core中IOC與DI的理解和使用ASP.NET
- 淺談 PHP 中異常類的使用PHP
- 淺談Gson和fastjson使用中的坑ASTJSON
- c#中lock的使用(用於預約超出限額的流程)C#
- 淺談C#更改令牌ChangeTokenC#
- 淺談C#取消令牌CancellationTokenSourceC#
- 淺談java8中的流的使用Java
- 淺談 JavaScript 中 Array 型別的方法使用JavaScript型別
- 淺談JavaScript中的thisJavaScript
- 淺談個性化推薦系統中的非取樣學習
- 淺談 JavaScript 中的防抖與節流(一)JavaScript
- 淺談JavaScript的型別轉換JavaScript型別
- Vuex與Busemit結合使用淺談Vuex使用方式VueMIT
- 淺談EventBus的使用原理
- 淺談微服務轉型微服務
- 淺談java中的反射Java反射
- 淺談react 中的 this 指向React
- 淺談Java中的HashmapJavaHashMap
- 淺談React中的diffReact
- 淺談C#可變引數paramsC#
- 淺談C#字串構建利器StringBuilderC#字串UI
- 淺談CSS3中display屬性的Flex佈局(轉)CSSS3Flex
- synchronized與Lock的區別與使用詳解synchronized
- 【JSON解析】淺談JSONObject的使用JSONObject
- VirtualDOM與DomDiff淺談
- C# modbus RTU 中使用到的 ushort[] 轉 int 與 int 轉 ushort[]C#
- 淺談Kotlin中的函式Kotlin函式
- 淺談CSS中的Position(定位)CSS
- 淺談Rowid中的行號
- 淺談Golang中select的用法Golang