多线程编程.死锁

来源:互联网 发布:大陆网络公知大v 编辑:程序博客网 时间:2024/05/29 09:13
//from 阿山NET的专栏

多线程编程(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
原创粉丝点击