有趣的多线程编程(4)——死锁 - 中国WEB开发者网络 (http://www.webasp.net) -- 技术教程 (http://www.webasp.net/article/) --- 有趣的多线程编程(4)——死锁 (http://www.webasp.net/article/28/27247.htm) | ||
| -- 作者:未知 -- 发布日期: 2006-02-07 | ||
|
// 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"); } }
因应之道,使用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(); } } }
| ||
| webasp.net |