有趣的多線程編程(4)——死結

來源:互聯網
上載者:User
編程|多線程

// 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


相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。