【设计原则和建议】 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,和其他第三方文章
因为本人水平有限,如有遗漏或谬误,还请各位高手指正