0

我一直在学习多线程编程并致力于解决哲学家就餐问题。我试图在休眠任何线程的情况下造成死锁。这是我正在使用的代码片段:

public class Program
    {
        const int NumberOfPhilosophers = 5;
        const int NumberOfForks = 5;
        const int EatingTimeInMs = 20;
        static object[] forks = new object[NumberOfForks];
        static Thread[] philosopherEatingThreads = new Thread[NumberOfPhilosophers];

        public static void Main(string[] args)
        {
            for (int i = 0; i < NumberOfForks; i++)
            {
                forks[i] = new object();
            }

            for (int i = 0; i < NumberOfPhilosophers; i++)
            {
                int philosopherIndex = i;

                philosopherEatingThreads[i] = new Thread(() => { DoWork(philosopherIndex); })
                {
                    Name = philosopherIndex.ToString()
                };

                philosopherEatingThreads[philosopherIndex].Start();
            }

        }

        public static void DoWork(int philosopherIndex)
        {
            int fork1Index = philosopherIndex;
            int fork2Index = (philosopherIndex + 1 ) % NumberOfForks;
            var fork1 = forks[fork1Index];
            var fork2 = forks[fork2Index];

            lock (fork1)
            {
                lock (fork2)
                {
                    Thread.Sleep(EatingTimeInMs);
                }
            }
        }
    }

在尝试了几次之后,我没有看到任何死锁。我知道没有遇到死锁并不意味着这段代码是线程安全的。例如,当我更改锁定语句并添加延迟时,我会导致死锁。

lock (fork1)
{
    Thread.Sleep(10);
    lock (fork2)
    {
        Thread.Sleep(EatingTimeInMs);
    }
}

我有两个问题:

  1. 一个接一个地使用两个锁语句是原子操作吗?
  2. 如果使用 Thread.Sleep() 导致代码片段死锁,这是否意味着代码片段不是线程安全的?

谢谢!

4

0 回答 0