0
点赞
收藏
分享

微信扫一扫

有趣的多线程编程(4)——死锁


// DeadLockSample.cs
// 分析一下为什么会发生死锁?

using System;
using System.Threading;

public class Test
{
static readonly object firstLock = new object();
static readonly object secondLock = new object();

static void Main()
{
new Thread(new ThreadStart(ThreadJob)).Start();

// Wait until we're fairly sure the other thread
// has grabbed firstLock
Thread.Sleep(500);

Console.WriteLine ("Locking secondLock");
lock (secondLock)
{
Console.WriteLine ("Locked secondLock");
Console.WriteLine ("Locking firstLock");
lock (firstLock)
{
Console.WriteLine ("Locked firstLock");
}
Console.WriteLine ("Released firstLock");
}
Console.WriteLine("Released secondLock");
}

static void ThreadJob()
{
Console.WriteLine ("/t/t/t/tLocking firstLock");
lock (firstLock)
{
Console.WriteLine("/t/t/t/tLocked firstLock");
// Wait until we're fairly sure the first thread
// has grabbed secondLock
Thread.Sleep(1000);
Console.WriteLine("/t/t/t/tLocking secondLock");
lock (secondLock)
{
Console.WriteLine("/t/t/t/tLocked secondLock");
}
Console.WriteLine ("/t/t/t/tReleased secondLock");
}
Console.WriteLine("/t/t/t/tReleased firstLock");
}
}

Locking firstLock

Locked firstLock


Locking secondLock


Locked secondLock


Locking firstLock

Locking secondLock

因应之道,使用Queue和Monitor:

//QueueMonitorThread.cs

using System;
using System.Collections;
using System.Threading;

public class Test
{
static ProducerConsumer queue;

static void Main()
{
queue = new ProducerConsumer();
new Thread(new ThreadStart(ConsumerJob)).Start();

Random rng = new Random(0);
for (int i=0; i < 10; i++)
{
Console.WriteLine ("Producing {0}", i);
queue.Produce(i);
Thread.Sleep(rng.Next(1000));
}
}

static void ConsumerJob()
{
// Make sure we get a different random seed from the
// first thread
Random rng = new Random(1);
// We happen to know we've only got 10
// items to receive
for (int i=0; i < 10; i++)
{
object o = queue.Consume();
Console.WriteLine ("/t/t/t/tConsuming {0}", o);
Thread.Sleep(rng.Next(1000));
}
}
}

public class ProducerConsumer
{
readonly object listLock = new object();
Queue queue = new Queue();

public void Produce(object o)
{
lock (listLock)
{
queue.Enqueue(o);
if (queue.Count==1)
{
Monitor.Pulse(listLock);
}
}
}

public object Consume()
{
lock (listLock)
{
while (queue.Count==0)
{
Monitor.Wait(listLock);
}
return queue.Dequeue();
}
}
}

Producing 0

Consuming 0

Producing 1

Consuming 1

Producing 2

Consuming 2

Producing 3

Consuming 3

Producing 4

Producing 5

Consuming 4

Producing 6

Consuming 5

                                         Consuming 6

Producing 7

Consuming 7

Producing 8

Consuming 8

Producing 9

Consuming 9

举报

相关推荐

0 条评论