有时我们lock一段代码或许要根据某个变量的值,值相同则不允许有两个或以上的方法并行运行,我在工作中就遇到了,有100个值,相同的参数值不能并行运行。
还有就是一个被lock的方法递归调用会不会死锁,因为需要lock同一个变量。答案当然是不会死锁。
下面是一个测试demo
class Program
{
private static object a = new object();
private static object b = new object();
private static object c = new object();
private static Hashtable list = Hashtable.Synchronized(new Hashtable());
static void Main(string[] args)
{
//所有i不相等的线程将同步执行并返回结果
new Thread(new ParameterizedThreadStart(delegate(object obj) {
Test(0, 2000);
Console.WriteLine("1");
})).Start();
new Thread(new ParameterizedThreadStart(delegate(object obj)
{
Test(1, 2000);
Console.WriteLine("1+");
})).Start();
//所有i==2的线程将顺序执行
new Thread(new ParameterizedThreadStart(delegate(object obj)
{
Test(2, 2000);
Console.WriteLine("2");
})).Start();
new Thread(new ParameterizedThreadStart(delegate(object obj)
{
Test(2, 2000);
Console.WriteLine("3");
})).Start();
new Thread(new ParameterizedThreadStart(delegate(object obj)
{
Test(2, 2000);
Console.WriteLine("4");
})).Start();
new Thread(new ParameterizedThreadStart(delegate(object obj)
{
Test(2, 2000);
Console.WriteLine("5");
})).Start();
new Thread(new ParameterizedThreadStart(delegate(object obj)
{
Test(2, 2000);
Console.WriteLine("6");
})).Start();
//两次lock同一变量不会死锁
new Thread(new ParameterizedThreadStart(delegate(object obj)
{
Test2(3, 2000);
Console.WriteLine("7");
})).Start();
Console.ReadKey();
}
/// <summary>
/// 对于i相同的线程进行阻塞保证不会并行多个
/// </summary>
/// <param name="i"></param>
/// <param name="j"></param>
public static void Test(int i,int j)
{
if (!list.ContainsKey(i))
list.Add(i, DateTime.Now);
lock (list[i])
{
Thread.Sleep(j);
}
}
//多次lock同一变量测试是否会死锁
public static void Test2(int i, int j, bool isFirstRun = true)
{
if (!list.ContainsKey(i))
list.Add(i, DateTime.Now);
lock (list[i])
{
Thread.Sleep(j);
if (isFirstRun)
Test2(i, j, false);
}
}
}
程序输出如下:
1+
2
1
3
7
4
5
6