我正在尝试使用MethodImplOptions.Synchronized方法表示法重现一些死锁:
using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.CompilerServices;
namespace Lab_01
{
class Program1
{
[MethodImpl(MethodImplOptions.Synchronized)]
static void Resource1(int starterIndex, bool startNext = true)
{
Console.WriteLine("Resource1 is used ({0})", starterIndex);
Thread.Sleep(1000);
if (startNext)
{
Resource2(starterIndex, false);
}
Console.WriteLine("Resource1 is free ({0})", starterIndex);
}
[MethodImpl(MethodImplOptions.Synchronized)]
static void Resource2(int starterIndex, bool startNext = true)
{
Console.WriteLine("Resource2 is used ({0})", starterIndex);
Thread.Sleep(1000);
if (startNext)
{
Resource1(starterIndex, false);
}
Console.WriteLine("Resource2 is free ({0})", starterIndex);
}
static void Main(string[] args)
{
Locker locker1 = new Locker();
Locker locker2 = new Locker();
new Thread(delegate()
{
Resource1(0);
}).Start();
new Thread(delegate()
{
Resource2(1);
}).Start();
}
}
}
我期待的是
但是当我启动它时它并没有锁定自己而且我得到了这个输出:
C:\Users\ginz\C#\19-\Lab_01\Lab_01\bin\Debug>Lab_01.exe
Resource1 is used (0)
Resource2 is used (0)
Resource2 is free (0)
Resource1 is free (0)
Resource2 is used (1)
Resource1 is used (1)
Resource1 is free (1)
Resource2 is free (1)
所以,第二个线程只在第一个线程结束时启动,但我认为它应该更早开始。这是为什么?
我知道可以使用lock
关键字简单地重现此行为,但在我的情况下,这是不恰当的方式:
Object obj1 = new Object(), obj2 = new Object();
new Thread(new ThreadStart(delegate()
{
lock (obj1)
{
Thread.Sleep(1000);
lock (obj2)
{
Thread.Sleep(500);
}
}
})).Start();
new Thread(new ThreadStart(delegate()
{
lock (obj2)
{
Thread.Sleep(1000);
lock (obj1)
{
Thread.Sleep(500);
}
}
})).Start();
在这种情况下你能帮我吗?
提前致谢, 梅德