DelphiThreadPool线程池(Delphi2009以上版本适⽤)在⽹上查Delphi线程池,结果发现寥寥⽆⼏。
看了半天源代码,弄得⼀头雾⽔,觉得不容易理解和使⽤,于是⾃⼰想写⼀个线程池。
什么样的线程池更好呢?
我觉得使⽤起来要可靠,并且⼀定要简单,这样才是更好的。
我写的线程池就是这样⼀个标准,使⽤⾮常简单,只传⼊⾃⼰要执⾏的⽅法就可以了,
其实⼤家最后就是关注⾃⼰要操作的⽅法,其余的交给线程池。全部源代码如下:
{
{单元:ThreadPoolUint}
{说明:线程池}
//
{Rev. 开发⽇期开发者  EMail}
{Ver.1.0.0  2011/05/05    孙⽟良  sunylat@gmail}
}
unit ThreadPoolUint;
{ 定义多线程共享读独占写条件编译}
{$DEFINE MULTI_THREAD_WRITE_READ}
interface
uses System.Classes, System.SysUtils, System.Math, System.Generics.Collections,
Vcl.Forms;
type
{ 要执⾏任务的记录}
TaskRec = record
isSynchronize : Boolean; { 是否需要同步执⾏}
TaskProc : TThreadProcedure; { 要执⾏任务的⽅法}
end;
{ 执⾏具体任务线程}
TExecuteThread = class( TThread )
private
FProc : TThreadProcedure; { 要执⾏的任务⽅法}
FIsCanTask : Boolean; { 是否可以执⾏任务}
FIsSynchronize : Boolean; { 是否⽤同步执⾏}
procedure showThreadID; { 显⽰线程编号(测试使⽤)}
protected
procedure Execute; override;
public
constructor Create( CreateSuspended : Boolean ); overload;
public
procedure StartTask( task : TaskRec ); { 执⾏任务}
end;
{ 线程池类(单例模式的类,做为全局使⽤的类)}
ThreadPool = class( TObject )
private
{$IFDEF MULTI_THREAD_WRITE_READ}
FMREWSync : TMREWSync; { 共享读独占写变量}
{$ENDIF}
FTaskQueue : TQueue< TaskRec >; { 要执⾏任务队列}
FTaskThreadList : TList< TExecuteThread >; { 执⾏任务线程List}
FThreadMin : Integer; { 最⼩线程数量}
FThreadMax : Integer; { 最⼤线程数量}
{ 共享读独占写⽅法}
procedure BeginWrite; { 独占写开始}
procedure EndWrite; { 独占写结束}
procedure BeginRead; { 共享读开始}
procedure EndRead; { 共享读结束}
procedure StopTaskAndFree; { 停⽌执⾏任务并释放相关资源}
protected
constructor CreateInstance( const minCount : Integer = 5;
const maxCount : Integer = 20 );
class function AccessInstance( Request : Integer;
const minCount : Integer = 5; const maxCount : Integer = 20 )
: ThreadPool;
public
constructor Create; { 构造函数}
destructor destroy; override; { 析构函数}
class function Instance( const minCount : Integer = 5;
const maxCount : Integer = 20 ) : ThreadPool; { 实例化函数,客户端调⽤此函数}
class procedure ReleaseInstance; { 释放资源函数,客户端调⽤此函数} procedure AddTask( task : TaskRec ); { 添加要执⾏的任务}
function IsHaveTask : Boolean; { 是否有要执⾏的任务}
procedure ExecuteTask; { 执⾏任务}
function DoNextTask( executeThread : TExecuteThread ) : Boolean; { 执⾏下⼀任务} function IsSuspend( executeThread : TExecuteThread ) : Boolean; { 挂起线程} function GetPoolState : string; { 得到线程池状态}
end;
implementation
{$J+}
{ MainUnit是为了测试引⼊的窗体单元,实际使⽤时候删除此单元和相关代码 }
uses MainUnit;
{ -----------------------------------------------------------------------------}
{ 构造函数}
constructor ThreadPool.Create;
begin
inherited Create;
raise Exception.CreateFmt( 'Utils类只能通过Instance⽅法来创建和访问%s的实例!',    [ ClassName ] );
end;
{ 创建实例⽅法}
constructor ThreadPool.CreateInstance( const minCount : Integer = 5;
const maxCount : Integer = 20 );
var
i : Integer;
begin
inherited Create;
{ 需要在构造函数中初始化数据全部在此初始化}
{$IFDEF MULTI_THREAD_WRITE_READ}
{ 创建多线程共享读独占写变量}
Self.FMREWSync := TMREWSync.Create;
{$ENDIF}
Self.FTaskQueue := TQueue< TaskRec >.Create; { 实例化要执⾏的任务队列}
Self.FTaskThreadList := TList< TExecuteThread >.Create; { 实例化执⾏任务线程List}  Self.FThreadMin := minCount; { 最⼩线程数量}
Self.FThreadMax := maxCount; { 最⼤线程数量}
{ 创建最⼩数量的线程}
for i := 0to minCount - 1do
begin
{ 把线程添加到线程List中}
Self.FTaskThreadList.Add( TExecuteThread.Create( true ) );
end;
end;
{ 析构函数}
destructor ThreadPool.destroy;
begin
{ 需要析构前完成操作全部在此完成}
Self.StopTaskAndFree; { 释放线程池资源}
{$IFDEF MULTI_THREAD_WRITE_READ}
{ 释放多线程共享读独占写变量}
Self.FMREWSync.Free;
{$ENDIF}
if AccessInstance( 0 ) = Self then
begin
AccessInstance( 2 );
end;
inherited destroy;
end;
class function ThreadPool.AccessInstance( Request : Integer;
const minCount : Integer = 5; const maxCount : Integer = 20 ) : ThreadPool;
const
FInstance : ThreadPool = nil;
begin
{
AccessInstance(0):不作任何处理,供释放实例对象时使⽤。
AccessInstance(1):存在该实例时直接使⽤,不存在时则创建该实例。
AccessInstance(2):返回⼀个空指针,⽤于重新设置实例。
}
case Request of
0 :
;
1 :
if not Assigned( FInstance ) then
begin
FInstance := CreateInstance( minCount, maxCount );
end;
2 :
FInstance := nil;
else
raise Exception.CreateFmt( ' %d 是AccessInstance()中的⾮法调⽤参数。', [ Request ] ); end;
Result := FInstance;
end;
{ 得到类实例}
class function ThreadPool.Instance( const minCount : Integer = 5;
const maxCount : Integer = 20 ) : ThreadPool;
begin
{ 返回实例}
Result := AccessInstance( 1, minCount, maxCount );
end;
{ 释放资源}
class procedure ThreadPool.ReleaseInstance;
begin
AccessInstance( 0 ).Free;
end;
{ ---- 类函数结束 ---- }
procedure ThreadPool.StopTaskAndFree;
var
whileCount : Integer; { while循环计数变量}
taskThread : TExecuteThread;
begin
{ 1,释放线程List}
try
Self.BeginWrite;
whileCount := 0; { while循环计数默认值为0}
while whileCount < unt do
begin
taskThread := Self.FTaskThreadList.Items[ whileCount ]; { 得到⼯作线程}
Self.FTaskThreadList.Delete( whileCount ); { 从线程列表中删除线程}
taskThread.Terminate; { 终⽌线程}
Inc( whileCount ); { while循环计数递增}
end;
finally
Self.EndWrite;
Self.FTaskThreadList.Free; { 释放线程List}
end;
{ 2,释放任务队列}
Self.FTaskQueue.Clear;
Self.FTaskQueue.Free;
end;
{ 独占写开始}
procedure ThreadPool.BeginWrite;
begin
{$IFDEF MULTI_THREAD_WRITE_READ}
Self.FMREWSync.BeginWrite;
{$ENDIF}
end;
{ 独占写结束}
procedure ThreadPool.EndWrite;
begin
{$IFDEF MULTI_THREAD_WRITE_READ}
Self.FMREWSync.EndWrite;
{$ENDIF}
end;
{ 共享读开始}
procedure ThreadPool.BeginRead;
begin
{$IFDEF MULTI_THREAD_WRITE_READ}
Self.FMREWSync.BeginRead;
{$ENDIF}
end;
{ 共享读结束}
procedure ThreadPool.EndRead;
begin
{$IFDEF MULTI_THREAD_WRITE_READ}
Self.FMREWSync.EndRead;
{$ENDIF}
end;
{ 给线程池添加任务}
procedure ThreadPool.AddTask( task : TaskRec );
begin
{ 添加任务到线程池中}
try
Self.BeginWrite;
Self.FTaskQueue.Enqueue( task ); { 把要执⾏任务加⼊任务队列} finally
Self.EndWrite;
end;
end;
{ 是否有要执⾏的任务}
function ThreadPool.IsHaveTask : Boolean;
var
temp : Boolean;
begin
temp := false;
try
Self.BeginRead;
{ 判断有要执⾏的任务}
if unt > 0then
begin
temp := true;
end;
finally
Self.EndRead;
end;
Result := temp;
end;
{ 执⾏任务}
procedure ThreadPool.ExecuteTask;
var
whileCount : Integer; { while循环计数变量}
isCanCreateThread : Boolean; { 是否可以创建新线程}
curThread : TExecuteThread;
begin
{ 在主界⾯memo中显⽰信息}
Form1.log( '开始执⾏任务' ); { 测试使⽤,正式使⽤删除}
if Self.IsHaveTask then
begin
{ 1,判断是否有可以执⾏任务线程,如果有直接让线程执⾏}
try
Self.BeginRead;
whileCount := 0; { while循环计数变量默认值为0}
while whileCount < unt do
begin
{ 判断当前线程为挂起状态}
if Self.FTaskThreadList.Items[ whileCount ].Suspended then
begin
Self.FTaskThreadList.Items[ whileCount ].Resume; { 唤醒挂起线程} end;
Inc( whileCount ); { while循环计数递增}
end;
finally
Self.EndRead;
{ 判断有要执⾏的任务}
if Self.IsHaveTask then
begin
{ 是否可以创建新线程默认值为false}
isCanCreateThread := false;
try
Self.BeginRead;
{ 判断当前线程总数⼩于最⼤线程数量}
if unt < Self.FThreadMax then
begin
isCanCreateThread := true;
{/ /是否可以创建新线程为true}
end;
finally
Self.EndRead;
{ 判断可以创建新线程}
if isCanCreateThread then
begin
while unt < Self.FThreadMax do
begin
{ 创建新线程}
curThread := TExecuteThread.Create( true );
析构方法try
Self.BeginWrite;
{ 把新线程加⼊线程List}
Self.FTaskThreadList.Add( curThread );
finally
Self.EndWrite;
end;
curThread.Resume;
end;
end;
end;
end;
end;
end;
end;
{ 执⾏下⼀任务}
function ThreadPool.DoNextTask( executeThread : TExecuteThread ) : Boolean; var
isDoNextTask : Boolean; { 是否执⾏下⼀任务}
nextTaskRec : TaskRec; { 下⼀任务结构}
temp : Boolean;
begin
temp := false; { 返回布尔值默认值为false}
try
isDoNextTask := false; { 是否执⾏下⼀任务默认值为false}
Self.BeginWrite;
{ 判断有要执⾏的任务}
if unt > 0then
begin
nextTaskRec := Self.FTaskQueue.Dequeue;
isDoNextTask := true; { 是否执⾏任务为true}
temp := true; { 返回布尔值为true}
end;
finally
Self.EndWrite;
{ 判断执⾏下⼀任务}
if isDoNextTask then
begin
executeThread.StartTask( nextTaskRec ); { 执⾏任务}
end;
end;
Result := temp;
end;
{ 判断线程是否需要挂起}
function ThreadPool.IsSuspend( executeThread : TExecuteThread ) : Boolean; var
temp : Boolean;
isRemove : Boolean;
begin
temp := false;
try
Self.BeginRead;
isRemove := false; { 是否从线程List中删除当前线程默认值为false}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。