.Net多线程、异步及线程同步总结(二):线程篇

      .Net中Thread类是最基本的线程类,位于System.Threading命名空间下。是用来创建并控制线程、设置线程优先级及获取线程状态的封装类。创建Thread类的实例要使用 ThreadStart 委托或 ParameterizedThreadStart 委托。当在Thread实例上调用Start方法时,就会在新的线程上执行与之关联的方法。在线程生存周期中,Thread实例必处于ThreadState定义的一个或多个状态中;通过Thread类还可以为线程设置优先级(但不保证底层操作系统一定接受);当与之关联的方法执行完毕,线程也就完成。

      示例1演示了通过ThreadStart 委托在新线程上执行无形参方法

//示例1的代码清单
using System;
using System.Threading;
public class MyClass
{
        public static void Main()
        {
                Thread th = new Thread(ThreadTest0);// 或者 new Thread(new ThreadStart(ThreadTest0));
                th.Start();
                Console.WriteLine("Wait for several seconds.");
                Console.Read();
        }        
        ///每秒钟输出一次托管线程ID及当前时间
        public static void ThreadTest0()
        {
                int i = 0;
                while(5>i)
                {
                        Thread.Sleep(1000);
                        Console.WriteLine("Thread ID:{0}\t\t\t\tTime:{1}",Thread.CurrentThread. ManagedThreadId,DateTime.Now.ToString("HH:mm:ss"));
                        i++;
                }
        }        
}

      示例1执行结果如图1:

图1

       示例2演示了通过ParameterizedThreadStart委在新线程上执行有一个形参的方法

//示例2代码清单
using System;
using System.Threading;
public class MyClass
{
        public static void Main()
        {                
                Thread th = new Thread(ThreadTest2);
                th.Start(5);
                Console.WriteLine("Wait for several seconds.");
                Console.Read();
        }        
        //按指定的次数每隔一分钟输出线程ID和当时时间。
        public static void ThreadTest2(object times)
        {
                int t = Convert.ToInt32(times);
                if(t<=0)
                        t = 5;
                int i = 0;
                while(t>i)
                {
                        Thread.Sleep(1000);
                        Console.WriteLine("Thread ID:{0}\t\t\t\tTime:{1}",Thread.CurrentThread.ManagedThreadId,DateTime.Now.ToString("HH:mm:ss"));
                        i++;                        
                }
        }
}

       示例2执行结果如图2:

图2

      如果关联的方法要求传递多个参数,则需要做些额外的工作。如果是个新方法,最直接的做法是将参数封装成一个类,则这个方法的就可以转变成只一个形参的方法了;如果这个方法已经存在并已被多个地方调用,则就不能直接这样了,不然就要修改所有调用的地方的代码,这时可以定义一个新的方法,新方法接收1个参数---参数类实例,新方法体里再调用原来的方法。

      另外一个更加OO的方式是,将多线程操作和参数都封装为一个类里。在这个类里原来的参数都作为成员变量(或属性),新线程上执行的方法可以转变成一个无参的私有方法,而执行多线程操作的代码可以封装成一个公开方法,供外部调用,当外部实例化类时将参数传递给构造函数,或者在外部调用公开方法前给实例属性赋值,示例3演示了这种方式:

//示例3代码清单
using System;
using System.Threading;
/// <summary>
/// 外部调用的类
/// </summary>
public class MyClass
{
        public static void Main()
        {                
                Console.WriteLine("Wait for several seconds.");
                for(int i=0;i<5;i++)
                {
                        Thread.Sleep(1000);
                        DateTime now = DateTime.Now;        
                        //实例化
                        ThreadExecute te = new ThreadExecute (now.Hour,now.Minute, now.Second);
                        //执行多线程
                        te.Execute();
                }
                Console.Read();
        }        
}

/// <summary>
/// 对多线程和参数进行封装
/// </summary>
public class ThreadExecute
{
        int h,        m,        s;
        /// <summary>
        /// 隐藏无参构造
        /// </summary>
        private ThreadExecute (){}
        /// <summary>
        /// 公开有参构造,参数为多线程执行所需要的参数
        /// </summary>
        public ThreadExecute (int h,int m,int s)
        {
                this.h = h;
                this.m = m;
                this.s = s;
        }
        /// <summary>
        /// 为外部公开的多线程执行入口方法
        /// </summary>
        public void Execute()
        {
                Thread th = new Thread(Print);
                th.Start();
        }
        /// <summary>
        /// 私有的,多线程所要执行的操作
        /// </summary>
        private void Print()
        {
                Console.WriteLine("H:{0},M:{1},S:{2}",this.h,this.m,this.s);
        }
}

       示例3执行结果如图3:

图3

posted @ 2011-08-22 09:34  沈沈  阅读(404)  评论(0编辑  收藏  举报