无法使用MethodImplOptions.Synchronized重现线程死锁

时间:2013-11-09 07:43:54

标签: c# .net multithreading synchronization deadlock

我正在尝试使用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();

        }
    }
}

我期待的是

  1. 启动第一个线程,仅锁定Resource1方法,等待1秒
  2. 当第一个线程处于休眠状态(此1秒)时,第二个线程启动并锁定第二个资源(Resource2)。它睡了1秒。
  3. 首先结束睡眠的线程,说第一个线程,想要锁定第二个资源,但它不能,因为它已经被锁定,并且无法释放,因为第二个线程处于相同的情况(它想锁定Recource1,但它已被锁定)。总之,常规的死锁情况。
  4. 但是当我启动它时它并没有锁定自己而且我得到了这个输出:

    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();
    

    在这种情况下你能帮我吗?

    提前致谢, 梅德

0 个答案:

没有答案