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 Self.FTaskQueue.count > 0 then
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
// 判断线程数量是否大于最小线程数量
if Self.FTaskThreadList.count > Self.FThreadMin then
begin
isRemove := true; // 是否从线程List中删除当前线程为true
end
else
begin
temp := true; // 是否挂起为true
end;
finally
Self.EndRead;
// 判断从线程List中删除当前线程
if isRemove then
begin
try
Self.BeginWrite;
// 从线程List中删除当前线程
Self.FTaskThreadList.Remove(executeThread);
finally
Self.EndWrite;
end;
end;
end;
Result := temp;
end;
// 得到线程池状态
function ThreadPool.GetPoolState: string;
var
temp: string; // 返回值变量
i: Integer; // 循环计数变量
curThread: TExecuteThread;
begin
temp := '线程状态:' + #13#10;;
temp := temp + '最小线程数:' + inttostr(Self.FThreadMin) + #13#10;
temp := temp + '最大线程数:' + inttostr(Self.FThreadMax) + #13#10;
try
Self.BeginRead;
temp := temp + '线程总数:' + inttostr(Self.FTaskThreadList.count) + #13#10;
temp := temp + #13#10;
temp := temp + '线程详细信息:' + #13#10;
temp := temp + #13#10;
for i := 0 to Self.FTaskThreadList.count - 1 do
begin
curThread := Self.FTaskThreadList.Items[i];
temp := temp + '线程-' + inttostr(i + 1) + #13#10;
temp := temp + '线程编号:' + inttostr(curThread.ThreadID) + #13#10;
// 是否挂起
if curThread.Suspended then
begin
temp := temp + '是否挂起: True' + #13#10;
end
else
begin
temp := temp + '是否挂起: False' + #13#10;
end;
// 是否可以执行任务
if curThread.FIsCanTask then
begin
temp := temp + '是否可以执行: True' + #13#10;
end
else
begin
temp := temp + '是否可以执行: False' + #13#10;
end;
// 是否同步执行任务
if curThread.FIsSynchronize then
begin
temp := temp + '是否同步执行: True' + #13#10;
end
else
begin
temp := temp + '是否同步执行: False' + #13#10;
end;
temp := temp + #13#10;
end;
finally
Self.EndRead;
end;
Result := Trim(temp);
end;
// -----------------------------------------------------------------------------
// 执行任务线程构造函数
constructor TExecuteThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := true;
Self.FIsCanTask := false; // 是否可以执行任务默认值为false
Self.FIsSynchronize := false; // 是否同步执行默认值为false
end;
// 显示线程编号(测试使用)
procedure TExecuteThread.showThreadID;
begin
with Form1 do
begin
Memo1.Lines.Add('停止执行任务线程编号:' + inttostr(Self.ThreadID))
end;
end;
// 执行任务线程的主方法
procedure TExecuteThread.Execute;
begin
while not Terminated do
begin
if Terminated then
begin
Break;
end;
// 判断可以执行任务
if Self.FIsCanTask then
begin
Self.FProc(); // 执行任务
end;
// 判断不执行任务
if ThreadPool.Instance.DoNextTask(Self) = false then
begin
// 显示执行任务线程编号
Synchronize(Self.showThreadID); // 测试使用,正式使用删除
// 判断挂起当前线程
if ThreadPool.Instance.IsSuspend(Self) then
begin
Self.Suspend; // 挂起
end
else // 不挂起则终止当前线程
begin
Self.Terminate; // 终止
end;
end;
// 使界面有反应
Application.ProcessMessages;
end;
end;
// 设置要执行的任务
procedure TExecuteThread.StartTask(task: TaskRec);
begin
Self.FProc := task.TaskProc; // 设置要执行的任务
Self.FIsSynchronize := task.isSynchronize; // 设置是否同步执行
Self.FIsCanTask := true; // 设置是否可以执行任务为true
end;
end.
演示例子代码:
unit MainUnit;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, System.DateUtils,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
Button3: TButton;
Button7: TButton;
teskCountEdt: TEdit;
Button8: TButton;
useTimeLab: TLabel;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button8Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure log(lgoInfo: string); // log方法
end;
var
Form1: TForm1;
repeatCount: Integer = 0;
startTime: TDateTime; // 开始时间
useTime: Double; // 用时
implementation
{$R *.dfm}
uses ThreadPoolUint;
procedure TaskFun;
var
count: Integer;
begin
// with Form1 do
// begin
//
// inc(repeatCount);
//
// Memo1.Lines.Add(FormatDateTime('yyyy-mm-dd hh:mm:ss', Now) +
// ' repeat count-' + IntToStr(repeatCount));
//
// // count := 50000;
// //
// // while count > 0 do
// // begin
// // Dec(count);
// // end;
//
// end;
count := 0;
while count <100000 do
begin
inc(count);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ThreadPool.Instance(5, 20);
self.log('线程池创建了');
end;
procedure TForm1.Button2Click(Sender: TObject);
var
task: TaskRec;
I: Integer;
timeStr: string;
posInt: Integer;
begin
startTime := Now;
useTimeLab.Caption := '0';
// 演示代码开始-----------------------
// 循环添加要执行的任务
// 1,添加要执行任务
for I := 0 to StrToInt(teskCountEdt.Text) - 1 do
begin
// 执行任务记录
task.isSynchronize := false;
task.TaskProc := TaskFun;
// 添加要执行的任务
ThreadPool.Instance.AddTask(task);
end;
// 2,让线程池执行任务
ThreadPool.Instance.ExecuteTask;
// 演示代码结束-----------------------
useTime := MilliSecondSpan(startTime, Now);
timeStr := FloatToStr(useTime);
posInt := Pos('.', timeStr);
Delete(timeStr, posInt, Length(timeStr) - (posInt - 1));
useTimeLab.Caption := '共用时: ' + timeStr + ' 毫秒';
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
self.log(ThreadPool.Instance.GetPoolState); // 显示线程池状态
end;
procedure TForm1.Button7Click(Sender: TObject);
begin
ThreadPool.ReleaseInstance;
self.log('线程池释放了');
end;
procedure TForm1.Button8Click(Sender: TObject);
begin
Memo1.Clear;
repeatCount := 0;
useTimeLab.Caption := '0';
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
ThreadPool.ReleaseInstance;
end;
procedure TForm1.log(lgoInfo: string);
begin
Memo1.Lines.Add('');
Memo1.Lines.Add(FormatDateTime('yyyy-mm-dd hh:mm:ss', Now) + ' ' +
trim(lgoInfo))
end;
end.
调用线程池的代码是:
//1,定义一个要执行任务的结构
task.isSynchronize := false;//是否同步执行
task.TaskProc := TaskFun;//要执行任务方法
// 2,向线程池添加要执行的任务
ThreadPool.Instance.AddTask(task);
// 3,让线程池执行任务
ThreadPool.Instance.ExecuteTask;