首页新闻找找看学习计划

C# Lock 锁定问题

1
悬赏园豆:20 [已解决问题] 解决于 2012-02-23 09:25

希望大虾说下Lock那些情况下会发生死锁,平时注意些什么。还有如果在lock里面跳出去了,锁定会不会解除。

lock(this)

return;

还有private readonly static object _LockMake = new object();锁定一个readonly 的可以吗?

群主的主页 群主 | 初学一级 | 园豆:23
提问于:2012-02-22 17:54
< >
分享
最佳答案
0

回答第一个:如果lock块中没有访问其他需要加锁的资源,那么不会死锁。如果在lock1块中又访问了另外的需要lock2的资源,那么需要注意可能引起死锁,注意不要互相需求锁(形成环型需求)就可以了,给你看个简单的例子

        class Test
{
private static object lock1 = new object();
private static object lock2 = new object();

public static void M1()
{
Console.WriteLine("M1: acquiring lock1");
lock (lock1)
{
Console.WriteLine("M1: got lock1");
Thread.Sleep(1000);
Console.WriteLine("M1: acquiring lock2");
lock (lock2)
{
Console.WriteLine("M1: got lock2 - impossible"); //永远不会执行
}
}
}

public static void M2()
{
Console.WriteLine("M2: acquiring lock2");
lock (lock2)
{
Console.WriteLine("M2: got lock2");
Thread.Sleep(1000);
Console.WriteLine("M2: acquiring lock1");
lock (lock1)
{
Console.WriteLine("M2: got lock1 - impossible"); //永远不会执行
                    }
}
}
}

static void Main(string[] args)
{
    Thread t1 = new Thread(Test.M1);
    Thread t2 = new Thread(Test.M2);
    t1.Start();
    t2.Start();

}


回答第二个:当然会解除。

收获园豆:20
水牛刀刀 | 大侠五级 |园豆:6350 | 2012-02-22 18:13

第三个:可以。

水牛刀刀 | 园豆:6350 (大侠五级) | 2012-02-22 18:49

@水牛刀刀: 第三个搬来就是readonly了,lock有啥意义?

Cuks | 园豆:200 (初学一级) | 2013-09-16 15:56
其他回答(2)
1

死锁是当被lock{}包裹的代码执行时间过长,后面的线程就得等在那里必须要等前面的执行完,执行完后锁就会自动解除,等后面的在执行的时候再锁上

sixserve | 园豆:17 (初学一级) | 2012-11-01 11:17
0
//我怀疑是由于你们测试的时候,代码运行的太快了,所以才不会锁住的
//所以我建议你在i--上加入一个线程睡眠操作
//以下是我的测试代码
//--------------
//更新
//将睡眠时间减少为100,事实上是有锁的效果,但不会死锁住的。神奇了。
class Program
{
    private readonly object _locker = new object();
    static void Main(string[] args)
    {
        Console.WriteLine("测试开始");
        //三种测试方式
        //每次测试一种
        TestWithTestInputInt();
        //TestWithTestInputObject();
        //TestWithLockTestWithOuterObject();
        //如果没有看到打印出“测试结束”或者其它信息,表示锁住了
        Console.WriteLine("测试结束");
        Console.Read();
    }
    /// <summary>
    /// 锁住自身,测试输入值参数
    /// </summary>
    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);
    }
    /// <summary>
    /// 锁住自身,测试输入object参数 -结果 锁住
    /// </summary>
    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);
    }
    /// <summary>
    /// 锁住自身,测试锁住外部object -结果 锁住
    /// </summary>
    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);
    }
}

 
火地晋 | 园豆:106 (初学一级) | 2013-07-27 18:14
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册