使用 lock(this)
进行同步
使用 lock(this)
能够实现线程同步,但是会导致类型缺乏健壮性,容易发生死锁。
下面的示例展示了一个使用 lock(this)
导致死锁的情况。
示例代码
SynchroThis.cs
cs
using System;
using System.Threading;
namespace SynchroThis
{
/// <summary>
/// 使用 this 来同步线程
/// 缺乏健壮性
/// </summary>
class SynchroThis
{
private int i = 0;
public void Work(Object state)
{
lock(this)
{
Console.WriteLine("i 的值为:{0}", i.ToString());
i++;
Thread.Sleep(200);
Console.WriteLine("i 自增 1 后的值为:{0}", i.ToString());
}
}
}
}
Program.cs
cs
using System;
using System.Threading;
namespace SynchroThis
{
class Program
{
static void Main(string args)
{
SynchroThis st = new SynchroThis();
// 恶意的使用者
Monitor.Enter(st);
// 正常的使用者
// 但是受到恶意使用者的影响
// 这里的完全正确,却被死锁
Thread t = new Thread(st.Work);
t.Start();
t.Join();
// 程序不会执行到这里
Console.WriteLine("使用结束");
Console.Read();
}
}
}
技巧
应当完全避免使用 this
对象和当前类型对象(typeof(classname)
)作为同步对象,而应该在类型中定义私有的同步对象,同时应使用 lock
而不是 Monitor
类型,这样可以有效的减少同步块不被释放的情况。