今天从公司辞职回来.从项目实践开发中得到不少经验..这里拿出来分享一下.公司做的是电力10KV以下配网..主要有工程量统计.生成报表.模块的拼接等需要计算的模块..这些模块会造成服务器性能下降.并且在线用户会达到200人..以自己的经验来看..搞个线程池..来做到同时计算的目的..
简单线程池存在一些问题,比如如果有大量的客户要求服务器为其服务,但由于线程池的工作线程是有限的,服务器只能为部分客户服务,其它客户提交的任务,只能在任务队列中等待处理。一些系统设计人员可能会不满这种状况,因为他们对服务器程序的响应时间要求比较严格,所以在系统设计时可能会怀疑线程池技术的可行性,但是线程池有相应的解决方案。调整优化线程池尺寸是高级线程池要解决的一个问题。主要有下列解决方案:
方案一:
动态增加工作线程 在一些高级线程池中一般提供一个可以动态改变的工作线程数目的功能,以适应突发性的请求。一旦请求变少了将逐步减少线程池中工作线程的数目。当然线程增加可以采用一种超前方式,即批量增加一批工作线程,而不是来一个请求才建立创建一个线程。批量创建是更加有效的方式。该方案还有应该限制线程池中工作线程数目的上限和下限。否则这种灵活的方式也就变成一种错误的方式或者灾难,因为频繁的创建线程或者短时间内产生大量的线程将会背离使用线程池原始初衷--减少创建线程的次数。举例:Jini中的TaskManager,就是一个精巧线程池管理器,它是动态增加工作线程的。SQL Server采用单进程(Single Process)多线程(Multi-Thread)的系统结构,1024个数量的线程池,动态线程分配,理论上限32767。
方案二:
优化工作线程数目 如果不想在线程池应用复杂的策略来保证工作线程数满足应用的要求,你就要根据统计学的原理来统计客户的请求数目,比如高峰时段平均一秒钟内有多少任务要求处理,并根据系统的承受能力及客户的忍受能力来平衡估计一个合理的线程池尺寸。线程池的尺寸确实很难确定,所以有时干脆用经验值。举例:在MTS中线程池的尺寸固定为100。
方案三:
一个服务器提供多个线程池 在一些复杂的系统结构会采用这个方案。这样可以根据不同任务或者任务优先级来采用不同线程池处理。举例:COM+用到了多个线程池。这三种方案各有优缺点。在不同应用中可能采用不同的方案或者干脆组合这三种方案来解决实际问题。
我采用的是方案三.根据不同任务或者任务优先级来采用不同线程池处理
Imports **.**.Common
Imports **.**.SystemFramework
Imports System
Imports System.Threading
Imports System.Collections
#Region "线程池类"
'''<summary>
'''--------------------------------------------------
''' Copyright (C) 2000-2010 ******有限公司
''' 文件名:ClkTaskDA.vb
''' 编写者:fanliang11
''' 功能:线程池,包括添加任务、取消任务、是否包含任务、重置线程池、关闭线程池等功能
'''编写日期:2008年05月15日
'''--------------------------------------------------
''' </summary>
Public Class ThreadPool
#Region "构造函数"
''' <summary>
''' 默认构造函数
''' 创建默认线程数的线程池
''' </summary>
Shared Sub New()
Initialize()
End Sub
#End Region
#Region "公共方法"
''' <summary>
''' 是否包含指定名称的任务
''' </summary>
''' <param name="pTaskName">任务名称</param>
''' <returns>如果包含返回true,否则返回false</returns>
Public Shared Function Contains(ByVal pTaskName As String) As Boolean
Dim containsTask As Boolean = False
SyncLock mPoolLock
containsTask = mTaskNameList.Contains(pTaskName)
End SyncLock
Return containsTask
End Function
''' <summary>
''' 获取等待执行的任务数
''' </summary>
''' <param name="pTaskType">任务类型</param>
''' <returns></returns>
Public Shared Function GetWaitingTaskNum(ByVal pTaskType As BoWeiTaskType) As Integer
Dim waitingTaskNum As Integer = 0
SyncLock mPoolLock
Select Case pTaskType
Case BoWeiTaskType.STATPROJECT
waitingTaskNum = mStatProjectQueue.Count
Exit Select
Exit Select
Case BoWeiTaskType.COMMON
waitingTaskNum = mCommonQueue.Count
Exit Select
End Select
End SyncLock
Return waitingTaskNum
End Function
''' <summary>
''' 添加任务至线程池
''' </summary>
''' <param name="pCallback">回调函数的委托</param>
''' <param name="pInformation">操作提示信息</param>
''' <returns>任务添加成功返回true;添加失败返回false</returns>
Public Shared Function QueueUserWorkItem(ByVal pCallback As WaitCallback, ByRef pInformation As String) As Boolean
Dim taskName As String = Guid.NewGuid().ToString()
Return QueueUserWorkItem(pCallback, Nothing, taskName, BoWeiThreadType.COMMON, pInformation)
End Function
''' <summary>
''' 添加任务至线程池
''' </summary>
''' <param name="pCallback">回调函数的委托</param>
''' <param name="pState">回调函数参数</param>
''' <param name="pInformation">操作提示信息</param>
''' <returns>任务添加成功返回true;添加失败返回false</returns>
Public Shared Function QueueUserWorkItem(ByVal pCallback As WaitCallback, ByVal pState As Object, ByRef pInformation As String) As Boolean
Dim taskName As String = Guid.NewGuid().ToString()
Return QueueUserWorkItem(pCallback, pState, taskName, BoWeiThreadType.COMMON, pInformation)
End Function
''' <summary>
''' 添加任务至线程池
''' </summary>
''' <param name="pCallback">回调函数的委托</param>
''' <param name="pTaskName">任务名</param>
''' <param name="pInformation">操作提示信息</param>
''' <returns>任务添加成功返回true;添加失败返回false</returns>
Public Shared Function QueueUserWorkItem(ByVal pCallback As WaitCallback, ByVal pTaskName As String, ByRef pInformation As String) As Boolean
Return QueueUserWorkItem(pCallback, Nothing, pTaskName, BoWeiThreadType.COMMON, pInformation)
End Function
''' <summary>
''' 添加任务至线程池
''' </summary>
''' <param name="pCallback">回调函数的委托</param>
''' <param name="pState">回调函数参数</param>
''' <param name="pTaskName">任务名</param>
''' <param name="pInformation">操作提示信息</param>
''' <returns>任务添加成功返回true;添加失败返回false</returns>
Public Shared Function QueueUserWorkItem(ByVal pCallback As WaitCallback, ByVal pState As Object, ByVal pTaskName As String, ByRef pInformation As String) As Boolean
Return QueueUserWorkItem(pCallback, pState, pTaskName, BoWeiThreadType.COMMON, pInformation)
End Function
''' <summary>
''' 添加任务至线程池
''' </summary>
''' <param name="pCallback">回调函数的委托</param>
''' <param name="pThreadType">处理类型</param>
''' <param name="pInformation">操作提示信息</param>
''' <returns>任务添加成功返回true;添加失败返回false</returns>
Public Shared Function QueueUserWorkItem(ByVal pCallback As WaitCallback, ByVal pThreadType As BoWeiThreadType, ByRef pInformation As String) As Boolean
Dim taskName As String = Guid.NewGuid().ToString()
Return QueueUserWorkItem(pCallback, Nothing, taskName, pThreadType, pInformation)
End Function
''' <summary>
''' 添加任务至线程池
''' </summary>
''' <param name="pCallback">回调函数的委托</param>
''' <param name="pState">回调函数参数</param>
''' <param name="pThreadType">处理类型</param>
''' <param name="pInformation">操作提示信息</param>
''' <returns>任务添加成功返回true;添加失败返回false</returns>
Public Shared Function QueueUserWorkItem(ByVal pCallback As WaitCallback, ByVal pState As Object, ByVal pThreadType As BoWeiThreadType, ByRef pInformation As String) As Boolean
Dim taskName As String = Guid.NewGuid().ToString()
Return QueueUserWorkItem(pCallback, Nothing, taskName, pThreadType, pInformation)
End Function
''' <summary>
''' 添加任务至线程池
''' </summary>
''' <param name="pCallback">回调函数的委托</param>
''' <param name="pTaskName">任务名</param>
''' <param name="pThreadType">处理类型</param>
''' <param name="pInformation">操作提示信息</param>
''' <returns>任务添加成功返回true;添加失败返回false</returns>
Public Shared Function QueueUserWorkItem(ByVal pCallback As WaitCallback, ByVal pTaskName As String, ByVal pThreadType As BoWeiThreadType, ByRef pInformation As String) As Boolean
Return QueueUserWorkItem(pCallback, Nothing, pTaskName, pThreadType, pInformation)
End Function
''' <summary>添加任务至线程池</summary>
''' <param name="pCallback">回调函数的委托</param>
''' <param name="pState">回调函数的参数</param>
''' <param name="pTaskName">任务名</param>
''' <param name="pThreadType">线程类型</param>
''' <param name="pInformation">操作提示信息</param>
''' <returns>添加任务成功返回true;添加任务失败返回false</returns>
Public Shared Function QueueUserWorkItem(ByVal pCallback As WaitCallback, ByVal pState As Object, ByVal pTaskName As String, ByVal pThreadType As BoWeiThreadType, ByRef pInformation As String) As Boolean
Dim callBack As New WaitingCallback(pCallback, pState, pTaskName, pThreadType)
SyncLock mPoolLock
If Not mTaskNameList.Contains(pTaskName) Then
'添加至任务名称队列
mTaskNameList.Add(pTaskName)
End If
End SyncLock
Select Case CInt(pThreadType)
Case 0
'Zip线程处理
SyncLock mStatProjectLock
mStatProjectQueue.Enqueue(callBack)
End SyncLock
mStatProjectTaskSignal.AddOne()
Exit Select
Case 1
'Common线程处理
SyncLock mCommonLock
mCommonQueue.Enqueue(callBack)
End SyncLock
mCommonTaskSignal.AddOne()
Exit Select
End Select
Return True
End Function
#End Region
#Region "事件定义"
Public Delegate Sub NoTaskEventHandle(ByVal eventArg As ThreadPoolNoTaskArg)
''' <summary>线程池无任务的事件</summary>
Public Shared Event NoTaskEvent As NoTaskEventHandle
#End Region
#Region "字段定义"
''' <summary>最大自动统计工程量线程数</summary>
Private Shared mMaxStatProjectCount As Integer = 4
''' <summary>最大COMMON线程数</summary>
Private Shared mMaxCommonThreadCount As Integer = 2
''' <summary>自动统计工程量任务控制信号对象</summary>
Private Shared mStatProjectTaskSignal As TaskSignal
''' <summary>COMMON任务控制信号对象</summary>
Private Shared mCommonTaskSignal As TaskSignal
''' <summary>任务队列(ZIP,DQP,ED, COMMON, EDScoreDetail)</summary>
Private Shared mStatProjectQueue As Queue
Private Shared mCommonQueue As Queue
''' <summary>任务名集合</summary>
Private Shared mTaskNameList As ArrayList
''' <summary>线程池中的运行线程集合</summary>
Private Shared mWorkingThreadList As ArrayList
''' <summary>线程池控制锁</summary>
Private Shared mPoolLock As New Object()
''' <summary>zip控制锁</summary>
Private Shared mStatProjectLock As New Object()
''' <summary>COMMON控制锁</summary>
Private Shared mCommonLock As New Object()
#End Region
''' <summary>回调对象</summary>
Private Class WaitingCallback
#Region "构造函数"
''' <summary>默认构造函数,初始化对象字段</summary>
''' <param name="pCallback">回调函数的委托</param>
''' <param name="pState">回调函数的参数</param>
''' <param name="pName">回调函数的线程名称</param>
''' <param name="pThreadType">线程类型</param>
Public Sub New(ByVal pCallback As WaitCallback, ByVal pState As Object, ByVal pName As String, ByVal pThreadType As BoWeiThreadType)
mCallback = pCallback
mState = pState
mName = pName
mThreadType = pThreadType
End Sub
#End Region
#Region "私有字段"
''' <summary>回调函数委托</summary>
Private mCallback As WaitCallback
''' <summary>回调函数的参数</summary>
Private mState As Object
''' <summary>回调方法的线程名称</summary>
Private mName As String
''' <summary>线程处理类型</summary>
Private mThreadType As BoWeiThreadType
#End Region
#Region "属性定义"
''' <summary>获取回调函数的委托</summary>
Public ReadOnly Property Callback() As WaitCallback
Get
Return mCallback
End Get
End Property
''' <summary>获取回调函数的参数</summary>
Public ReadOnly Property State() As Object
Get
Return mState
End Get
End Property
''' <summary>获取回调线程的优先级</summary>
Public ReadOnly Property ThreadType() As BoWeiThreadType
Get
Return mThreadType
End Get
End Property
''' <summary>回调方法的线程名称</summary>
Public ReadOnly Property Name() As String
Get
Return mName
End Get
End Property
#End Region
End Class
#Region "私有方法"
''' <summary>初始化线程池</summary>
Private Shared Sub Initialize()
'创建任务名称集合
mTaskNameList = New ArrayList()
'创建任务队列
mStatProjectQueue = New Queue()
mCommonQueue = New Queue()
'创建运行线程集合
mWorkingThreadList = New ArrayList()
'创建任务控制信号对象
mStatProjectTaskSignal = New TaskSignal()
mCommonTaskSignal = New TaskSignal()
For i As Integer = 0 To mMaxStatProjectCount - 1
'创建自动统计工程量运行线程
Dim workThread As Thread = Nothing
workThread = New Thread(New ThreadStart(AddressOf ProcessZIPQueuedItems))
mWorkingThreadList.Add(workThread)
workThread.IsBackground = True
'workThread.ApartmentState = ApartmentState.STA
workThread.SetApartmentState(ApartmentState.STA)
workThread.Start()
Next
For l As Integer = 0 To mMaxCommonThreadCount - 1
'创建COMMON运行任务
Dim workThread As Thread = Nothing
workThread = New Thread(New ThreadStart(AddressOf ProcessCOMMONQueuedItems))
mWorkingThreadList.Add(workThread)
workThread.IsBackground = True
workThread.Start()
Next
End Sub
''' <summary>处理自动统计工程量等待任务队列里的任务</summary>
Private Shared Sub ProcessZIPQueuedItems()
While True
'等待一个任务
mStatProjectTaskSignal.WaitOne()
While GetWaitingTaskNum(BoWeiTaskType.STATPROJECT) > 10
Thread.Sleep(20)
End While
'获取下一个任务的回调对象
Dim callback As WaitingCallback = Nothing
SyncLock mStatProjectLock
callback = GetNextTask(BoWeiThreadType.STATPROJECT)
End SyncLock
If callback IsNot Nothing Then
'执行对调函数
Try
callback.Callback.Invoke(callback.State)
Catch e As Exception
Finally
Try
SyncLock mPoolLock
mTaskNameList.Remove(callback.Name)
If mStatProjectQueue.Count = 0 Then
Dim noTaskArg As New ThreadPoolNoTaskArg()
noTaskArg.TaskType = BoWeiTaskType.STATPROJECT
RaiseEvent NoTaskEvent(noTaskArg)
GC.Collect()
End If
End SyncLock
Catch
End Try
End Try
End If
End While
End Sub
''' <summary>处理COMMON等待任务队列里的任务</summary>
Private Shared Sub ProcessCOMMONQueuedItems()
While True
'等待一个任务
mCommonTaskSignal.WaitOne()
'获取下一个任务的回调对象
Dim callback As WaitingCallback = Nothing
SyncLock mCommonLock
callback = GetNextTask(BoWeiThreadType.COMMON)
End SyncLock
If callback IsNot Nothing Then
'执行对调函数
Try
callback.Callback.Invoke(callback.State)
Catch e As Exception
Finally
Try
SyncLock mPoolLock
mTaskNameList.Remove(callback.Name)
If mCommonQueue.Count = 0 Then
Dim noTaskArg As New ThreadPoolNoTaskArg()
noTaskArg.TaskType = BoWeiTaskType.COMMON
RaiseEvent NoTaskEvent(noTaskArg)
GC.Collect()
End If
End SyncLock
Catch
End Try
End Try
End If
End While
End Sub
''' <summary>
''' 获取下一个等待任务
''' </summary>
''' <param name="pThreadType">任务类型</param>
''' <returns>返回任务的回调对象</returns>
Private Shared Function GetNextTask(ByVal pThreadType As BoWeiThreadType) As WaitingCallback
Dim callback As WaitingCallback = Nothing
Try
Select Case pThreadType
Case BoWeiThreadType.STATPROJECT
'自动统计工程量处理
If mStatProjectQueue.Count > 0 Then
callback = DirectCast(mStatProjectQueue.Dequeue(), WaitingCallback)
End If
Exit Select
Case BoWeiThreadType.COMMON
'COMMON处理
If mCommonQueue.Count > 0 Then
callback = DirectCast(mCommonQueue.Dequeue(), WaitingCallback)
End If
Exit Select
End Select
Catch e As Exception
callback = Nothing
End Try
Return callback
End Function
#End Region
End Class
#End Region
呵呵..小弟水平有限..如有不足之处..请大虾们指出..
实践中可以看出线程池技术对于服务器程序的性能改善是显著的。线程池技术在服务器领域有着广泛的应用前景。希望这项技术能够应用到您的多线程服务程序中。