当前位置: 首页 > 编程日记 > 正文

简单ThreadPool实现

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

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

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

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

ContractedBlock.gifExpandedBlockStart.gifThreadPoolEx
  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.gifExpandedBlockStart.gifWorkItem
 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.gifExpandedBlockStart.gifWorkQueue
 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

相关文章:

CSS中强大的EM

使用CSS也好久了&#xff0c;但一直都是在使用“px”来设置Web元素的相关属性&#xff0c;未敢使用“em”。主要原因是&#xff0c;对其并不什么了解&#xff0c;只知道一点概念性的东西&#xff0c;前段时间在项目中要求使用“em”作为单位设置元素&#xff0c;所以从头对“em…

16.1、python初识面向对象(1)

初识面向对象 楔子 你现在是一家游戏公司的开发人员&#xff0c;现在需要你开发一款叫做<人狗大战>的游戏&#xff0c;你就思考呀&#xff0c;人狗作战&#xff0c;那至少需要2个角色&#xff0c;一个是人&#xff0c; 一个是狗&#xff0c;且人和狗都有不同的技能&#…

1080 Graduate Admission

1.因为这道题第一次认真想了高考录取的规则&#xff0c;对学生按照先总分再gE的原则进行从高到低排序&#xff0c;排名允许重复。再按照排名高到低对每个学生的每个志愿进行遍历&#xff0c;当一个学生处理完&#xff0c;再进行下一个。 2.由于最后是要输出学生的原始序号&…

vc++实现无进程无DLL无硬盘文件无启动项的ICMP后门后门程序

客户端 #include <winsock2.h>#include <stdio.h>#include <stdlib.h> #pragma comment(lib,"ws2_32.lib") char SendMsg[256]; /* The IP header */typedef struct iphdr {unsigned int h_len:4; //4位首部长度unsigned int version:4; //IP版本…

arm linux 启动之一:汇编启动到start_kernel

描述arm linux启动的概要过程&#xff0c;以S5PV210(Cortex A8)为例&#xff0c;本文描述第一个阶段。 一、arm linux的引导 uboot在引导arm linux&#xff08;uImage镜像&#xff09;到SDRAM之后&#xff0c;通过bootm命令对uImage镜像的64个字节头进行解释&#xff0c;获取li…

Sql Server 因为触发器问题导致数据库更新报错“在触发器执行过程中引发了错误,批处理已中止”的问题处理...

在维护一个非常旧的项目时&#xff0c;由于该项目版本已经非常老了&#xff0c;而且在客户现场运行的非常稳定&#xff0c;更要命的是本人目前没有找到该项目的代码&#xff0c;为了处理一个新的需求而且还不能修改程序代码&#xff0c;于是决定从数据库入手&#xff0c;毕竟该…

1070 Mooncake

1. 一道典型的贪心题&#xff0c;策略是尽可能地多出售单价高的月饼。 2. 开始有一个用例没有通过&#xff0c;看了参考书&#xff0c;说是质量虽然给的都是整数&#xff0c;但是为了计算不出错&#xff0c;需要声明为浮点型。改了以后果然就通过了&#xff0c;但是个中原理不…

Java数组合并,完成排序,从时间复杂度,和空间复杂度考虑

2019独角兽企业重金招聘Python工程师标准>>> 提供方法&#xff0c;直接调用&#xff0c;支持任意个数组的合并成一个数组&#xff0c;并且完成排序&#xff0c;每个数组元素个数不定。需要提供两个方法&#xff0c;分别做到时间复杂度最低、空间复杂度最低。并说明两…

WPF中Auto与*的差别

Auto 表示自己主动适应显示内容的宽度, 如自己主动适应文本的宽度,文本有多长,控件就显示多长. * 则表示按比例来分配宽度. <ColumnDefinition Width"3*" /> <ColumnDefinition Width"7*" /> 相同,行能够这样定义 <RowDefinition Height&qu…

个人电脑优化方案

2009年4月13日 文件删除--系统默认磁盘清理--批处理清除无用文件--使用优化软件如优化大师 Codeecho off echo 正在清除系统垃圾文件&#xff0c;请稍等 del /f /s /q %systemdrive%\*.tmp del /f /s /q %systemdrive%\…

1037 Magic Coupon

1. 贪心算法题&#xff0c;贪心策略&#xff1a;两组乘子相乘&#xff0c;每个数字至多用一次&#xff0c;希望得到最大的乘积。那么让A组绝对值最大的正数和B组最绝对值最大的正数相乘&#xff0c;次大的和次大的相乘……同样的让A组绝对值最大的负数和B组绝对值最大的负数相乘…

综合布线系统入门及应用(二)

一、工程材料用量估计 1、信息模块及水晶头用量统计 信息插座与工位数量1:1&#xff0c;在增加5%的余量 跳线&#xff1a;一般需要2条&#xff0c;工位信息面板到设备&#xff0c;交换机到配线架&#xff0c;每根条线2个水晶头&#xff0c;预留10%-15%。 2、线槽用量统计 根据办…

如何查看服务器有多少网站--免费工具

一台虚拟主机上到底有多少个网站或者说同一ip下有多少个域名和网站&#xff1f;这是站长们都很关心的&#xff0c;因为这样可以知道你的站到底和谁是邻居&#xff0c;有时候如果你和百度黑名单上的垃圾站在同一空间下&#xff0c;你也会受到牵连。 那么怎 ...中间左侧广告 一台…

二分法在算法题中的4种常见应用(cont.)

目录 1.查找单调序列中是否存在满足某条件的元素 2.寻找序列中第一个(最后一个)满足某条件的元素的位置 3.给定一个定义在[L,R]上的单调函数f(x)&#xff0c;求方程f(x)0的根 4.快速幂的递归和迭代求法 1.查找单调序列中是否存在满足某条件的元素 //二分区间为左闭右闭的[l…

Minimum Path Sum

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. 格子取数问题&#xff0c;另dp[i][j]表示走…

Thorntail 2.2.0提供从WildFly Swarm自动迁移的特性

自6月底宣布把WildFly Swarm2018.5.0改名为Thorntail2.0.0以来&#xff0c;Red Hat在8月中旬以后的三个周里发布了Thorntail 2.1.0版本和2.2.0版本。除了许多Bug修复外&#xff0c;尤其是和MicroProfile相关的&#xff0c;新特性还包括&#xff1a;\\符合MicroProfile 1.3\通过…

Depth Bias

在dx中的depth bias要以如下形式调用 inline DWORD F2DW( float f ) { return *((DWORD*)&f); } m_pD3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(1)); m_pD3DDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW(0.001)); 总之&#xff0c;奇怪的api。转载…

(C++)用upper_bound函数取代自己写的二分查找

int a[maxn];int j upper_bound(ai1,an,(long long)a[i]*p)-a; 以上代码的作用是 在a[i1]~a[n-1]找到第一个大于a[i]*p的数&#xff0c;将其下标返回给j 注意&#xff1a; 1.函数是左闭右开的 2.末尾要减去数组的坐标a 3.不加long long强制类型转换可能丢分

gsoap使用总结

WebService、soap、gsoap基本概念 WebService服务基本概念&#xff1a;就是一个应用程序&#xff0c;它向外界暴露出一个可以通过web进行调用的API&#xff0c;是分布式的服务组件。本质上就是要以标准的形式实现企业内外各个不同服务系统之间的互调和集成。 soap概念&#xff…

SQL时间相关 - SQL日期,时间比较

SQL Server 中时间比较 例子: select count(*) from table where DATEDIFF ([second], 2004-09-18 00:00:18, 2004-09-18 00:00:19) > 0 说明 select DATEDIFF(day, time1 , time2) 对应示例语句如下 select DATEDIFF(day, 2010-07-23 0:41:18, 2010-07-23 23:41:18) …

SQL Server 2008 的CDC功能

CDC(Change Data Capture)通过对事务日志的异步读取&#xff0c;记录DML操作的发生时间、类型和实际影响的数据变化&#xff0c;然后将这些数据记录到启用CDC时自动创建的表中。通过cdc相关的存储过程&#xff0c;可以获取详细的数据变化情况。由于数据变化是异步读取的&#x…

1010 Radix

目录 总结 解题过程 总结 1. 短小精悍的一道二分算法题&#xff0c;总体思路是&#xff0c;将字符串1(如果tag不是1将两个字符串调换一下即可)转化为10进制&#xff0c;再用二分法看能否找到另一个进制使得两个字符串的10进制数相等。 2. 本题的三个函数关系是binarySearch…

喜闻乐见的const int *p、int* const p、const int* const p

不废话直接代码示例&#xff1a; 1 void f(const int *p) {2 3 int b 10;4 5 *p 10; // error6 7 p &b; // fine8 9 } 10 11 void f(int* const p) { 12 13 int b 10; 14 15 *p 10; // fine 16 17 p &b; // error 18 19 } 20 21 v…

Microsoft Visual Studio 2012 添加实体数据模型

Microsoft Visual Studio 2012 添加实体数据模型 1、创建一个web项目 2、添加ADO实体数据模型&#xff0c;如下图&#xff1a; 3、选择 从数据库生成&#xff0c;然后下一步 4、新建连接&#xff0c;如下图&#xff1a; 5、填写服务器名等&#xff0c;如下图&#xff1a; 6、选…

5.1软件升级的小阳春

现在正在去白山的车上&#xff0c;刚睡醒。习惯性的拿出手机上网&#xff0c;UCWEB提醒有最新版本升级&#xff0c;使用尚邮接收邮件的时候同样提醒有信版本升级。 公司产品9.0也正式完成&#xff0c;昨天整个小组的同事开始在领地咖啡馆&#xff0c;进行新需求的确认。 4月末5…

1030 完美数列(二分解法)

1. 将整型序列从小到大排序后&#xff0c;这道题的本质是&#xff0c;对于每一个元素i&#xff0c;找出最后一个满足p*A[i]>A[j]的元素j&#xff0c;可以转化为找出第一个不满足p*A[i]>A[j]也即p*A[i]<A[j]的元素j。再用j-1。 2.LL product (LL)p*A[i];这里后面两个…

javascript变量声明 及作用域

javascript变量声明提升(hoisting) http://openwares.net/js/javascript_declaration_hoisting.html 可能要FQ一下 javascript的变量声明具有hoisting机制&#xff0c;JavaScript引擎在执行的时候&#xff0c;会把所有变量的声明都提升到当前作用域的最前面。 先看一段代码 123…

【转载】全面理解javascript的caller,callee,call,apply概念(修改版)

今天写PPlayer&#xff0c;发现有段代码引起了我的兴趣&#xff1a; var Class { create: function() { return function() { this.initialize.apply(this, arguments); } } } 这是高手写的&#xff0c;实现了创建一个类&#xff08;其实就是对象&#xff0c;函数对象&#xf…

springMVC自定义全局异常

SpringMVC通过HandlerExceptionResolver处理程序异常&#xff0c;包括Handler映射&#xff0c;数据绑定以及目标方法执行时所发生的异常。 SpringMVC中默认是没有加装载HandlerExceptionResolver&#xff0c;我们需要在SpringMVC.xml中配置 <mvc:annotation-driven /> 1、…

1030 完美数列(two pointers解法)

1. 这道题出现在二分法&#xff0c;但是特殊之处在于&#xff0c;双指针是嵌套的&#xff0c;程序看上去有些像暴力枚举&#xff0c;但其实是利用了&#xff0c;如果i<j&#xff0c;a[i]*p>a[j]&#xff0c;那么一定有k在[i,j]范围内&#xff0c;a[i]*p>a[k]&#xff…