// 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 |
新闻热点
疑难解答