大可山博客[GDI+,WPF, .Net图形图像]

WPF,WinForms,asp.net开发,图形图像处理系统研究 (Johnson Blog)      [信奉:凡事靠自己] MSN:a3news(at)hotmail.com QQ:329325120

原创 有趣的多线程编程(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

发表于 @ 2006年01月27日 11:48:00|评论(loading...)

新一篇: AIX 5L 学习大纲/简易教程(1)(未经许可,请勿COPY) | 旧一篇: 有趣的多线程编程(3)——线程内部是如何进行的?

用户操作
[即时聊天] [发私信] [加为好友]
大可山(Johnson)
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
大可山(Johnson)的公告
MSN:a3news(at)hotmail.com,从2007年8月8日起笔名改为:大可山(以前叫阿山Net)
Q:329325120
引用本人原作,请注明出处。
文章分类
收藏
软件开发
你的灯亮着吗?(RSS)
图书出版
大溪水的博客(RSS)
图形图像
C#新型报表工具 XDesigner(RSS)
存档
软件项目交易
Csdn Blog version 3.1a
Copyright © 大可山(Johnson)