以下代码是教授在课堂上提供的多线程示例。我是编码新手(第一门课程)。我已阅读过多线程和使用锁。阅读理论很有趣。 var fun = Theory.Read(多线程);实际上编码线程和锁似乎让我感到困惑 试图理解下面代码中的两个线程将如何表现。从测试代码看起来看起来像lock1不会释放而message2没有被排队,但我可能错了。看起来存在同步问题。这是一个僵局的例子吗? 我也想知道如果使用两个不同的队列,为什么需要锁和线程。我没有看到共享资源。 有没有办法修复此代码以防止同步问题?
private static object Lock1 = new object(); // Protect MessageQueueOne
private static object Lock2 = new object(); // Protect MessageQueueTwo
private static Queue<string> MessageQueueOne = new Queue<string>();
private static Queue<string> MessageQueueTwo = new Queue<string>();
private static void AddMessages(string message1, string message2)
{
lock (Lock1)
{
// (1) Thread 1 is here...
MessageQueueOne.Enqueue(message1);
lock (Lock2)
{
MessageQueueTwo.Enqueue(message2);
}
}
}
private static void RemoveMessages()
{
lock (Lock2)
{
if (MessageQueueTwo.Count > 0)
{
// (2) Thread 2 is here...
Console.WriteLine(MessageQueueTwo.Dequeue());
}
lock (Lock1)
{
if (MessageQueueOne.Count > 0)
{
Console.WriteLine(MessageQueueOne.Dequeue());
}
}
}
}
private static void Main()
{
Task taskOne = Task.Run(() =>
{
for (int i = 0; i < 100; ++i)
{
AddMessages($"Message One: {DateTime.Now}", $"Message Two: {DateTime.UtcNow}");
Thread.Sleep(25);
}
});
Task taskTwo = Task.Run(() =>
{
for (int i = 0; i < 100; ++i)
{
RemoveMessages();
Thread.Sleep(25);
}
});
taskOne.Wait();
taskTwo.Wait();
Console.Write("Tasks are finished");
Console.ReadKey();
}
答案 0 :(得分:0)
帖子中的代码是死锁的经典示例,并且预计会在大多数情况下死锁。请参阅Wikipedia有关死锁的文章中的更多链接。
导致死锁的原因:一个线程锁定“lock1”并等待“lock2”,另一个线程同时锁定“lock2”并在获取“lock1”后释放它,这将永远不会被等待释放线程。
标准解决方案