class StateObject
{
private int State1 = 5;
private int State2 = 5;
Object _Lock1 = new object();
Object _Lock2 = new object();
public void ChangeState1()
{
lock (_Lock1)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "拿到了第1把锁");
lock (_Lock2)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "拿到了第2把锁");
if (State1 == 5)
{
Thread.Sleep(1);
State1++;
State2++;
Console.WriteLine("State1: " + State1 + " : " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("State2: " + State2 + " : " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1);
}
State1 = 5;
State2 = 5;
}
}
}
public void ChangeState2()
{
lock (_Lock2)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "拿到了第2把锁");
lock (_Lock1)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "拿到了第1把锁");
if (State1 == 5)
{
Thread.Sleep(1);
State1++;
State2++;
Console.WriteLine("State1: " + State1 + " : " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("State2: " + State2 + " : " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1);
}
State1 = 5;
State2 = 5;
}
}
}
}
static void Main(string[] args)
{
StateObject State = new StateObject();
for (int i = 0; i < 5; i++)
{
Task t1 = new Task(State.ChangeState1);
t1.Start();
Task t2 = new Task(State.ChangeState2);
t2.Start();
}
Console.ReadKey();
}
运行结果
10拿到了第1把锁
12拿到了第2把锁
会发现程序会出现卡死现象,因为当两个任务分别获取了lock1和lock2之后,就会无限等待另一个锁,这样就会造成两个任务都无法继续运行。为了避免这种情况出现,应该在编程开始的设计阶段,就设计好锁定顺序。
修改ChangeState2函数代码
public void ChangeState2()
{
lock (_Lock1)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "拿到了第1把锁");
lock (_Lock2)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "拿到了第2把锁");
if (State1 == 5)
{
Thread.Sleep(1);
State1++;
State2++;
Console.WriteLine("State1: " + State1 + " : " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("State2: " + State2 + " : " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1);
}
State1 = 5;
State2 = 5;
}
}
程序执行结果
6拿到了第1把锁
6拿到了第2把锁
State1: 6 : 6
State2: 6 : 6
12拿到了第1把锁
12拿到了第2把锁
State1: 6 : 12
State2: 6 : 12
10拿到了第1把锁
10拿到了第2把锁
State1: 6 : 10
State2: 6 : 10
11拿到了第1把锁
11拿到了第2把锁
State1: 6 : 11
State2: 6 : 11
...