【設計原則和建議】 lock
lock是.net中最常用的鎖
了解lock機制,引用類型,值類型,字符串和應用程序域的朋友可能對以下的內容都很熟悉了
1.先來看看推薦的lock代碼
class LockDemo
{
private static object asyncLock = new object();//使用static object作為互斥資源
public static void Test()
{
lock (asyncLock)//保證該方法是線程安全的
{
// 程序代碼
}
}
private object asyncLock2 = new object();//使用object作為互斥資源
public void Test2()
{
lock (asyncLock2)//保持該方法是線程安全的
{
// 程序代碼
}
}
}
2.請保證被lock的對象不會為null
object o = null;
lock (o)//如果o有可能為null 會拋出異常
{
}
3.如果類本身是public的 絕對不要在類的內部使用lock(this)
- 因為從外部有可能lock這個實例
4.嚴禁lock(typeof(MyType)) ,如果myType具有公開訪問性
5.嚴禁lock(typeof(int)) ,所有的基本類型也是一致的
6.嚴禁lock("string"),所有想lock同一個string的代碼都慘了
7.嚴禁lock值類型,例如lock(int)...會自動裝箱 (只能在Monitor.Enter 模擬,編輯器會阻止lock(int))
8.必要時候雙重檢查防止代碼重復執行
private static bool condition = true;
public static void Test3()
{
if (condition)
{
lock (asyncLock)//雖然CLR已經提供了很多的方法,不過這個經典模式還是很常用的
{
if (condition)
{
condition = false;
}
}
}
}
9.lock的基本實現,大家應該都很熟悉了
object o = new object();
Monitor.Enter(o);
try
{
//代碼
}
finally
{
Monitor.Exit(o);
}
10.CLR中有兩種鎖可以不進內核模式,一個是自旋鎖,另外一個就是lock,這兩個速度都比較快,適合時間很短的鎖定 (如果是進內核模式的鎖 至少就30ms了)
- 有朋友指出了lock是混合模式,驗證中...
11.使用lock編程簡單,比讀寫鎖,信號量等使用方便
12.因為性能和編程原因,某些時候不要使用lock
- 簡單操作用Interlocked 類自帶的一些操作
- 短時間鎖定,自旋鎖更快
- 如果可以,優先使用無lock的代碼,例如.net新增的線程安全的集合類
- 適當的時候使用讀寫鎖取代lock (讀多寫少)
- 長時間鎖定考慮信號量等方案 (例如異步IO操作)
13.一部分類本身提供了一些對象用于鎖定
- Hashtable.SyncRoot
部分內容引用自MSDN,和其他第三方文章
因為本人水平有限,如有遺漏或謬誤,還請各位高手指正
浙公網安備 33010602011771號