//我怀疑是由于你们测试的时候,代码运行的太快了,所以才不会锁住的
//所以我建议你在i--上加入一个线程睡眠操作
//以下是我的测试代码
//--------------
//更新
//将睡眠时间减少为100,事实上是有锁的效果,但不会死锁住的。神奇了。
class Program
{
private readonly object _locker = new object();
static void Main(string[] args)
{
Console.WriteLine("测试开始");
//三种测试方式
//每次测试一种
TestWithTestInputInt();
//TestWithTestInputObject();
//TestWithLockTestWithOuterObject();
//如果没有看到打印出“测试结束”或者其它信息,表示锁住了
Console.WriteLine("测试结束");
Console.Read();
}
///
/// 锁住自身,测试输入值参数
///
public static void TestWithTestInputInt()
{
//测试方式0-1 -可锁
//new Thread(() => new Program().TestInputInt(21)).Start();
//new Thread(() => new Program().TestInputInt(22)).Start();
//new Thread(() => new Program().TestInputInt(23)).Start();
//new Program().TestInputInt(24);
//测试方式0-2 -可锁
new Program().TestInputInt(21);
new Program().TestInputInt(22);
new Program().TestInputInt(23);
}
///
/// 锁住自身,测试输入object参数 -结果 锁住
///
public static void TestWithTestInputObject()
{
//测试方式2-1 -可锁
//new Thread(() => new Program().TestInputObject(21)).Start();
//new Thread(() => new Program().TestInputObject(22)).Start();
//new Thread(() => new Program().TestInputObject(23)).Start();
//new Program().TestInputObject(24);
//测试方式2-2 -可锁
//new Program().TestInputObject(21);
//new Program().TestInputObject(22);
//new Program().TestInputObject(23);
}
///
/// 锁住自身,测试锁住外部object -结果 锁住
///
public static void TestWithLockTestWithOuterObject()
{
//测试方式1-1 -可锁
//new Thread(() => new Program().LockTestWithOuterObject(21)).Start();
//new Thread(() => new Program().LockTestWithOuterObject(22)).Start();
//new Thread(() => new Program().LockTestWithOuterObject(23)).Start();
//new Program().LockTestWithOuterObject(24);
//测试方式1-2 -可锁
//new Program().LockTestWithOuterObject(21);
//new Program().LockTestWithOuterObject(22);
//new Program().LockTestWithOuterObject(23);
}
public void LockTestWithOuterObject(int msg)
{
lock (_locker)
{
Thread.Sleep(100);
}
Console.WriteLine(msg);
}
public void TestInputObject(object i)
{
lock (this)
{
int num = (int)i;
if (num > 10)
{
Thread.Sleep(100);
num--;
TestInputObject(num);
}
}
Console.WriteLine(i);
}
public void TestInputInt(int num)
{
lock (this)
{
if (num > 10)
{
Thread.Sleep(100);
num--;
TestInputInt(num);
}
}
Console.WriteLine(num);
}
}
不会发生死锁,因为你每次传递的是一个值,可以说是不同的地址。所以每次锁定的地址都不一样,不会发生死锁现象!
如果参数是个引用类型的话就会发生死锁,这个是值类型不会发生死锁!
不会发生死锁。您可以试试如下的语句
using System;
namespace Test
{
class Test
{
static void Main()
{
object lockObj = new object();
lock (lockObj)
{
lock (lockObj)
{
Console.WriteLine("Hello, world");
}
}
}
}
}
您会发现这个程序可以正确的输出 hello,world.
原因我想应该是Lock语句对 “同一个线程多次锁同一个对象不予理会"。所以,您的递归函数中第一次的lock语句会保证不会有多个线程同时执行test函数,而在test函数内部调用lock时会不予理会。
但是提醒您一下,http://msdn.microsoft.com/zh-cn/library/c5kehkcz(VS.80).aspx
msdn中明确的说明lock (this)是个不好的习惯。
会,因为第一次调用test()函数时,就已经把this锁定了,如果i的值大于10的话就会递归调用test()函数,此时会再次对this加锁,但是this在上一层调用时已经锁定了,所以就会一直阻塞在加锁的地方等待上一层调用释放this,然而,第二层的递归调用因为阻塞不能运行到函数返回的地方,就导致第一层的程序运行不出lock块,即,第一层的程序始终不能将this解除锁定.就造成第一层调用test()函数和第二层调用的test()函数对this临界资源的无限等待导致死锁.