随笔-53  评论-46  文章-0 

自定义线程池-c#的简单实现

下面是代码,希望大家提出更好的建议:

1.ThreadManager.cs

using System;

using System.Threading;

using System.Collections;

 

namespace CustomThreadPool

{

    /// <summary>

    /// 线程管理器,会开启或唤醒一个线程去执行指定的回调方法

    /// </summary>

    public class ThreadManager

    {

        private static ArrayList threadList = new ArrayList();  //线程列表,静态

       

        //不允许创建实例

        private ThreadManager()

        {

        }

 

        /// <summary>

        /// 静态方法,开启或唤醒一个线程去执行指定的回调方法

        /// </summary>

        /// <param name="waitCallback">委托实例</param>

        /// <param name="obj">传递给回调方法的参数</param>

        /// <param name="timeOut">当没有可用的线程时的等待时间,以毫秒为单位</param>

        /// <returns></returns>

        public static bool QueueUserWorkItem(WaitCallback waitCallback, Object obj, int timeOut)

        {

            //锁住共享资源,实现线程安全

            lock(threadList)

            {

                try

                {

                    //如果线程列表为空,填充线程列表

                    if (threadList.Count == 0)

                    {

                        InitThreadList();

                    }

 

                    long startTime = DateTime.Now.Ticks;

 

                    do

                    {

                        //遍历线程列表,找出可用的线程

                        foreach(MyThread myThread in threadList)

                        {

                            //线程为空,需要创建线程

                            if (myThread.T == null)

                            {

                                myThread.Start(waitCallback, obj, false);

                                return true;

                            }

                            else if (myThread.T.ThreadState == ThreadState.Suspended)

                            {//线程为挂起状态,唤醒线程

                                myThread.Start(waitCallback, obj, true);

                                return true;

                            }

                        }

 

                        //在线程 Sleep 前释放锁

                        Monitor.PulseAll(threadList);

                        Thread.Sleep(500);

 

                    }while (((DateTime.Now.Ticks - startTime) / 10000) < timeOut);

                }

                finally

                {

                    Monitor.Exit(threadList);

                }

            }

           

 

            return false;

        }

 

        //使用 MyThread 对象填充线程列表,注意,这个时候线程并没有启动

        private static void InitThreadList()

        {

            threadList = new ArrayList();

            for (int i = 0; i < 10; i++)

            {

                MyThread t = new MyThread();

                threadList.Add(t);

            }

        }

 

    }

}

 

2.MyThread.cs

using System;

using System.Threading;

 

namespace CustomThreadPool

{

    /// <summary>

    /// 封装 .NET 框架提供的 Thread

    /// </summary>

    internal class MyThread

    {

        private Thread t;       //线程

        private WaitCallback w; //委托,这里直接用 .NET 框架自带的,也可以根据需要自己定义一个

        private Object o;       //传递给符合委托的回调方法的参数值,根据委托的定义而定

 

        /// <summary>

        /// 执行回调方法的线程

        /// </summary>

        public Thread T

        {

            get

            {

                return t;

            }

        }

 

        public MyThread()

        {

        }

 

        /// <summary>

        /// 开启新线程或唤醒线程,去执行回调方法

        /// </summary>

        /// <param name="w">用回调方法实例化了的委托实例</param>

        /// <param name="o">传递给回调方法的参数值</param>

        /// <param name="isSuspend">true 表示线程为挂起状态,false 则表示线程还没创建</param>

        public void Start(WaitCallback w, Object o, bool isSuspend)

        {

            //开启新线程或唤醒线程前,先设置

            this.w = w;

            this.o = o;

 

            //线程为挂起状态,唤醒线程继续执行

            if (isSuspend)

            {

                t.Resume();

            }

            else

            {//线程还没有创建,创建一个新线程,并执行

                t = new Thread(new ThreadStart(this.ThreadProc));

                t.Start();

            }

        }

 

        /// <summary>

        /// 线程执行的方法

        /// </summary>

        private void ThreadProc()

        {

            //死循环,使线程唤醒后不是退出,而是继续通过委托执行回调方法

            while (true)

            {

                //通过委托执行回调方法

                w(o);

                t.Suspend();

            }

        }

    }

}

 

3.Test.cs

using System;

using System.Threading;

 

namespace CustomThreadPool

{

    /// <summary>

    /// 测试自定义线程池

    /// </summary>

    class Test

    {

        /// <summary>

        /// 应用程序的主入口点。

        /// </summary>

        [STAThread]

        static void Main(string[] args)

        {

            //

            // TODO: 在此处添加代码以启动应用程序

            //

 

            for (int i = 0; i < 5; i++)

            {

                Console.WriteLine("Start thread {0}", i.ToString());

                Thread t = new Thread(new ThreadStart(WorkThread));

                t.Start();

            }

 

            Console.ReadLine();

            Thread.CurrentThread.Abort();

        }

 

        public static void WorkThread()

        {

            for (int i = 0; i < 10; i++)

            {

                if (i % 2 == 0)

                {

                    if (!ThreadManager.QueueUserWorkItem(new WaitCallback(ThreadProcOne), i, 2000))

                    {

                        Console.WriteLine("Failed" + i.ToString());

                    }

                }

                else

                {

                    if (!ThreadManager.QueueUserWorkItem(new WaitCallback(ThreadProcTwo), i, 2000))

                    {

                        Console.WriteLine("Failed" + i.ToString());

                    }

                }

            }

 

            Thread.CurrentThread.Abort();

        }

 

        public static void ThreadProcOne(Object stateInfo)

        {

            Console.WriteLine("Test custom threadpool:" + ((int)stateInfo).ToString());

        }

 

        public static void ThreadProcTwo(Object stateInfo)

        {

            Console.WriteLine("Change work:" + ((int)stateInfo).ToString());

        }

    }

}

posted on 2006-11-19 00:02 hzman 阅读(...) 评论(...) 编辑 收藏