一个演示多线程操作及同步的C#程序

作者:Enjoying .NET  来源:博客园  发布时间:2006-03-07 18:57  阅读:450 次  原文链接   [收藏]  
/* 
 * Envionment: Win2kServer+VC#.NET2005
 * Author:     WandyWang 
 * Verion:     1.0
 * Date:       06-3-7
 * Abstract:   演示C#中多线程操作及其同步,示例的原型来自于C#Primer5.7节,细节有所改动 
 
*/

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

/*
 * 三个线程:主线程,ping线程(PING.play),pong线程(PONG.play)
 * 主线程  - 输出PING对象和PONG对象的Count属性值 用绿色
 * ping线程 - 对PING.Count加1,输出"ping" 用黄色
 * pong线程 - 对PONG.Count加1,输出"ping" 用红色
 * 线程同步:使用Mutex变量进行同步,不让三个线程的输出颜色混乱
 * 输出  :当去掉同步语句时会出现颜色混乱,但加上同步,则不会出现三个线程输出颜色混乱
 *      根据睡眠时间和输出的交错次数可以看出各个线程得到相等的调度优先权
 * 
*/

namespace CSPrimer5_7
{
    
class TestThread
    
{
        
static void Main( string[] args )
        
{
            pingpong PING 
= new pingpong( " ping "20 );
            pingpong PONG 
= new pingpong( " pong "100 );

            
//创建两个子线程ping和pong
            Thread ping = new Thread( new ThreadStart(PING.play) );
            Thread pong 
= new Thread( new ThreadStart(PONG.play) );

            pong.Start();
            ping.Start();
            
           
            
//主线程和两个子线程并发执行
            while (ping.IsAlive || pong.IsAlive)
            
{
                
/*
                 * Console.ForegroundColor = ConsoleColor.Green;
                 * Console.Write(" " + PING.Count.ToString() + " " + PONG.Count.ToString());
                 * 两句有可能分开执行,即执行完第一句则转入子线程,
                 * 然后再回来执行下句,所以有时候输出的数字不是绿色
                 * 
                 * 在这两句的上面添加 pingpong.mut.WaitOne();
                 * 下面添加 pingpong.mut.ReleaseMutex();
                 * 就可以解决主线程和进程ping pong的同步问题
                 
*/


                pingpong.mut.WaitOne();

                Console.ForegroundColor 
= ConsoleColor.Green;
                Console.Write(
" " + PING.Count.ToString() + " " + PONG.Count.ToString());

                pingpong.mut.ReleaseMutex();

                Thread.Sleep(
100);

                
//主线程在此等待ping线程退出
                ping.Join();
            }
           

            
//暂停屏幕
            Console.ReadLine();
        }

    }


    
class pingpong
    
{
        
//有属性的字段命名:_identifier
        
//它的属性名:Identifier
        
//没有属性的字段:identifier
        private int delay;
        
private string str;
        
private int max;
        
public static Mutex mut = new Mutex();
                           
        
//构造函数,函数名与类名相同,一般用public修饰,无返回值
        public pingpong( string str, int delay )
        
{
            
this.str = str;
            
this.delay = delay;
            
this.max = 100;
        }


        
private int _count;
        
public int Count
        
{
            
get
            
{
                
return _count;
            }

        }


        
public void play()
        

           
            
while ( true )
            
{               
                
/*
                 * 若没有 mut.WaitOne();和 mut.ReleaseMutex();
                 * 则ping和pong线程在交错执行时输出的颜色有可能会不时所期望的
                 * 即ping有可能输出为红色,pong有可能输出为黄色
                 * 但是此处还没解决主从线程中的输出混乱问题
                 * 刚开始输出的0 0可能不是绿色
                 
*/

                mut.WaitOne();

                
if(str.IndexOf( 'i' ) != -1)
                    Console.ForegroundColor 
= ConsoleColor.Yellow;
                
else 
                    Console.ForegroundColor 
= ConsoleColor.Red;

                Console.Write( 
this.str );

                mut.ReleaseMutex();
             
                
this._count++;
                Thread.Sleep( 
this.delay );
                
if ( _count >= max )
                    
return;
                
//mut.ReleaseMutex(); 原此句放在此处,但会出现AbandonedMutexException异常

                
/* 因为:(from MSDN)
                 * "如果线程在拥有互斥体时终止,则称此互斥体被放弃。
                 *  此互斥体被设置为终止状态,
                 *  下一个等待的线程获得所属权。
                 *  如果没有线程拥有互斥体,则互斥体状态为终止。
                 *  从 .NET Framework 2.0 版开始,需要该互斥体的下一个线程将引发 
                 *  AbandonedMutexException。在 .NET Framework 2.0 版之前,这样不会引发任何异常。
                 * "
                 * 所以:
                 * 将mut.ReleaseMutex();放在此处,最后ping进程的最后一个输出后会
                 * "在拥有互斥体时终止",会引发AbandonedMutexException异常               
                 
*/

            }
             
        }

    }

}

posted @ 2010-07-08 17:39  gllg  阅读(473)  评论(0编辑  收藏  举报