简单ThreadPool实现

由于最近需要用多线程处理一些问题,一开始我用了.net默认的ThreadPool,感觉不是很适合。于是我自己实现了一个简单的ThreadPool。

写的比较简单,有兴趣的朋友一起看看,共同改进。

 代码主要由ThreadPoolEx,WorkItem,WorkQueue组成。   

推荐使用新版本:http://www.cnblogs.com/ITAres/archive/2009/08/25/1553800.html

 

ContractedBlock.gif ExpandedBlockStart.gif ThreadPoolEx
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Text;
  5using System.Threading;
  6using System.Collections;
  7
  8namespace NetDragon.ThreadPoolEx
  9ExpandedBlockStart.gifContractedBlock.gif{
 10    public class ThreadPoolEx
 11ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 12        private WorkQueue _workQueue = new WorkQueue();
 13
 14        public int MaxThreadCount = 10;
 15        public int MinThreadCount = 2;
 16        private Hashtable _threadTable = null;
 17
 18        private int _threadCount = 0;
 19        private int _inUseWorkThread = 0;
 20
 21        public double IdleTimeout = 10;
 22
 23        public ThreadPoolEx():this(10,2,2)
 24ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 25        }

 26
 27        public ThreadPoolEx(int maxThreadCouont, int minThreadCount, int idleTimeout)
 28ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 29            MaxThreadCount = maxThreadCouont;
 30
 31            MinThreadCount = minThreadCount;
 32
 33            IdleTimeout = idleTimeout;
 34
 35            _threadTable = Hashtable.Synchronized(new Hashtable(MaxThreadCount));
 36        }

 37
 38        public void QueueUserWorkItem(WaitCallback waitCallback, object objParams)
 39ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 40            EnqueueWorkItem(waitCallback, objParams);
 41        }

 42
 43        private void EnqueueWorkItem(WaitCallback waitCallback,object objParams)
 44ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 45ExpandedSubBlockStart.gifContractedSubBlock.gif            WorkItem workItem = new WorkItem() 
 46            
 47                WorkCallback = waitCallback,
 48                ObjParams = objParams
 49            }
;
 50
 51            _workQueue.Push(workItem);
 52
 53            if (_inUseWorkThread + _waitWorkItem > _threadTable.Count)
 54ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 55                StartThread();
 56            }

 57        }

 58
 59        private void StartThread()
 60ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 61            if (_threadTable.Count < MaxThreadCount)
 62ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 63                ++_threadCount;
 64
 65                Thread thread = new Thread(ProcessWorkItems);
 66
 67                thread.IsBackground = true;
 68
 69                thread.Name = "ThreadPoolEx #" + _threadCount;
 70
 71                thread.Priority = ThreadPriority.Normal;
 72
 73                _threadTable[thread] = System.DateTime.Now;
 74
 75                thread.Start();
 76            }

 77        }

 78
 79        private void ProcessWorkItems()
 80ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 81
 82            try
 83ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 84                while (true)
 85ExpandedSubBlockStart.gifContractedSubBlock.gif                {
 86                    WorkItem workItem = _workQueue.Pop();
 87
 88                    if (workItem == null)
 89ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
 90                        bool isTimeout = CurThreadIsTimeOut();
 91
 92                        if (isTimeout)
 93ExpandedSubBlockStart.gifContractedSubBlock.gif                        {
 94                            if (_threadTable.Count > MinThreadCount)
 95ExpandedSubBlockStart.gifContractedSubBlock.gif                            {
 96                                _threadTable.Remove(Thread.CurrentThread);
 97                                break;
 98                            }

 99                        }

100
101                        System.Threading.Thread.Sleep(100);
102                    }

103                    else
104ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
105
106                        try
107ExpandedSubBlockStart.gifContractedSubBlock.gif                        {
108                            _threadTable[Thread.CurrentThread] = System.DateTime.Now;
109                            Interlocked.Increment(ref _inUseWorkThread);
110
111                            workItem.Execute();
112                        }

113                        catch (Exception)
114ExpandedSubBlockStart.gifContractedSubBlock.gif                        {
115                            // log something
116                        }

117                        finally
118ExpandedSubBlockStart.gifContractedSubBlock.gif                        {
119                            Interlocked.Decrement(ref _inUseWorkThread);
120                        }

121                    }

122                }

123            }

124            catch (ThreadAbortException)
125ExpandedSubBlockStart.gifContractedSubBlock.gif            {
126                Thread.ResetAbort();
127            }

128            finally
129ExpandedSubBlockStart.gifContractedSubBlock.gif            {
130                if (_threadTable.Contains(Thread.CurrentThread))
131ExpandedSubBlockStart.gifContractedSubBlock.gif                {
132                    _threadTable.Remove(Thread.CurrentThread);
133                }

134            }

135        }

136
137        private bool CurThreadIsTimeOut()
138ExpandedSubBlockStart.gifContractedSubBlock.gif        {
139            DateTime lastAliveTime = (DateTime)_threadTable[Thread.CurrentThread];
140
141            DateTime curTime = System.DateTime.Now;
142
143            double waitSeconds = (curTime - lastAliveTime).TotalSeconds;
144
145            if(waitSeconds > IdleTimeout)
146ExpandedSubBlockStart.gifContractedSubBlock.gif            {
147                return true;
148            }

149
150            return false;
151
152        }

153
154        private int _waitWorkItem
155ExpandedSubBlockStart.gifContractedSubBlock.gif        {
156            get
157ExpandedSubBlockStart.gifContractedSubBlock.gif            {
158                return _workQueue.Count;
159            }

160        }

161
162        public int ThreadCount
163ExpandedSubBlockStart.gifContractedSubBlock.gif        {
164            get
165ExpandedSubBlockStart.gifContractedSubBlock.gif            {
166                return _threadTable.Count;
167            }

168        }

169    }

170}

171

 

ContractedBlock.gif ExpandedBlockStart.gif WorkItem
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text;
 5using System.Threading;
 6
 7namespace NetDragon.ThreadPoolEx
 8ExpandedBlockStart.gifContractedBlock.gif{
 9    class WorkItem
10ExpandedSubBlockStart.gifContractedSubBlock.gif    {
11        public WaitCallback WorkCallback;
12
13        public object ObjParams;
14
15        public void Execute()
16ExpandedSubBlockStart.gifContractedSubBlock.gif        {
17            WorkCallback(ObjParams);
18        }

19    }

20}

21

 

ContractedBlock.gif ExpandedBlockStart.gif WorkQueue
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text;
 5
 6namespace NetDragon.ThreadPoolEx
 7ExpandedBlockStart.gifContractedBlock.gif{
 8    class WorkQueue
 9ExpandedSubBlockStart.gifContractedSubBlock.gif    {
10        private static object threadLock = new object();
11
12        private Queue<WorkItem> _workQueue = new Queue<WorkItem>();
13
14        public WorkItem Pop()
15ExpandedSubBlockStart.gifContractedSubBlock.gif        {
16            lock (threadLock)
17ExpandedSubBlockStart.gifContractedSubBlock.gif            {
18                if (_workQueue.Count > 0)
19ExpandedSubBlockStart.gifContractedSubBlock.gif                {
20                    return _workQueue.Dequeue();
21                }

22                return null;
23            }

24        }

25
26
27        public void Push(WorkItem workItem)
28ExpandedSubBlockStart.gifContractedSubBlock.gif        {
29            lock (threadLock)
30ExpandedSubBlockStart.gifContractedSubBlock.gif            {
31                _workQueue.Enqueue(workItem);
32
33            }

34        }

35
36        public int Count
37ExpandedSubBlockStart.gifContractedSubBlock.gif        {
38            get
39ExpandedSubBlockStart.gifContractedSubBlock.gif            {
40                return _workQueue.Count;
41            }

42        }

43    }

44}

45

 源代码下载

简单线程池实现v2版本

转载于:https://www.cnblogs.com/ITAres/archive/2009/03/27/1423414.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值