delphi新语法之泛型实现的对象池模板

现在的DELPHI因为支持泛型的语法,所以也能支持模板编程了。

// 标准模板

unit UntPools;

interface

uses

Classes, SysUtils, UntThreadTimer;

type

{ 这是一个对像池, 可以池化所有 TObject 对像 }

{ 用法:

在一个全局的地方定义

var

Pooler: TObjectPool;

用到的地方

obj := Pooler.LockObject as Txxx;

try

finally

Pooler.UnlockObject;

end;

初始化

initialization

Pooler := TObjectPool.Create(要收集的类名)

finallization

Pooler.Free;

end;

}

//池中对象 状态

TPoolItem = class

private

FInstance: TObject; //对象

FLocked: Boolean; //是否被使用

FLastTime:TDateTime;//最近活跃时间

public

constructor Create(AInstance: TObject;const IsLocked :Boolean = True);

destructor Destroy; override;

end;

//对象池

TObjectPool = class

private

FCachedList: TThreadList;//对象池 中 对象 列表

FMaxCacheSize,FMinCacheSize: Integer; //对象池最大值,最小值  如不设置系统默认为 20

FCacheHit: Cardinal; //调用对象池 中 对象的 次数

FCreationCount: Cardinal; //创建对象次数

FObjectClass: TClass;

FRequestCount: Cardinal; //调用对象池次数

FAutoReleased: Boolean; //自动释放空闲的对象

FTimer:TThreadedTimer; //多线程计时器

FHourInterval:Integer;  //设置间隔时间(小时)

function GetCurObjCount:Integer;

function GetLockObjCount:Integer;

procedure IniMinPools;//初始化最小池对象

procedure SetFHourInterval(iValue:Integer);

protected

function CreateObject: TObject;// 创建对象

procedure OnMyTimer(Sender: TObject);

public

constructor Create(AClass: TClass;MaxPools,MinPools:Integer);

destructor Destroy; override;

function LockObject: TObject;//获取对象

procedure UnlockObject(Instance: TObject); //释放对象

property ObjectClass: TClass read FObjectClass;

property MaxCacheSize: Integer read FMaxCacheSize;//池子大小

property CacheHit: Cardinal read FCacheHit; //调用池子中对象次数

property CreationCount: Cardinal read FCreationCount;//创建对象次数

property RequestCount: Cardinal read FRequestCount;//请求池次数

property RealCount : Integer  read GetCurObjCount;//池中对象数量

property LockObjCount: Integer read GetLockObjCount;//池子繁忙的对象数量

property HourInterval: Integer read FHourInterval write SetFHourInterval;

procedure StartAutoFree; //开启自动回收

procedure StopAutoFree; //关闭自动回收

end;

{ TObjectPool<T> }

{ 同样是对像池, 但支持模板 }

{ 用法:

在一个全局的地方定义

var

Pooler: TObjectPool<要收集的类名>;

用到的地方

obj := Pooler.LockObject;

try

finally

Pooler.UnlockObject;

end;

初始化

initialization

Pooler := TObjectPool<要收集的类名>.Create;

finallization

Pooler.Free;

end;

}

TObjectPool<T: class> = class(TObjectPool)

public

constructor Create(const MaxPools:Integer = 0;const MinPools:Integer = 0);

function LockObject: T;

end;

implementation

{TPoolItem }

const

MSecsPerMins = SecsPerMin * MSecsPerSec;

//返回相差的分钟

function MyMinutesBetWeen(const ANow, AThen: TDateTime): Integer;

var

tmpDay:Double;

begin

tmpDay := 0;

if ANow < AThen then

tmpDay := AThen - ANow

else

tmpDay := ANow - AThen;

Result := Round(MinsPerDay * tmpDay);

end;

constructor TPoolItem.Create(AInstance: TObject;const IsLocked :Boolean);

begin

inherited Create;

FInstance := AInstance;

FLocked := IsLocked;

FLastTime := Now;

end;

destructor TPoolItem.Destroy;

begin

if Assigned(FInstance) then FreeAndNil(FInstance);

inherited;

end;

{ TObjectPool }

constructor TObjectPool.Create(AClass: TClass; MaxPools, MinPools: Integer);

begin

inherited Create;

FObjectClass := AClass;

FCachedList := TThreadList.Create;

FMaxCacheSize := MaxPools;

FMinCacheSize := MinPools;

if FMaxCacheSize = 0 then FMaxCacheSize := 20;  //系统默认为20个并发

if FMinCacheSize > FMaxCacheSize then FMinCacheSize := FMaxCacheSize;//系统默认最小值为0

FCacheHit := 0;

FCreationCount := 0;

FRequestCount := 0;

IniMinPools; //初始化最小池对象

//计时销毁

FTimer := TThreadedTimer.Create(nil); //计时

FHourInterval := 4; //默认空闲4小时则回收

FTimer.Interval := MSecsPerMins * MinsPerHour * FHourInterval;

FTimer.OnTimer := OnMyTimer;

end;

function TObjectPool.CreateObject: TObject;

begin

Result := FObjectClass.NewInstance;

if Result is TDataModule then

TDataModule(Result).Create(nil)

else if Result is TComponent then

TComponent(Result).Create(nil)

else if Result is TPersistent then

TPersistent(Result).Create

else Result.Create;

end;

destructor TObjectPool.Destroy;

var

I: Integer;

LockedList: TList;

begin

if Assigned(FCachedList) then

begin

LockedList := FCachedList.LockList;

try

for I := 0 to LockedList.Count - 1 do

TPoolItem(LockedList[I]).Free;

finally

FCachedList.UnlockList;

FCachedList.Free;

end;

end;

FTimer.Free;

inherited;

end;

function TObjectPool.GetCurObjCount: Integer;

var

LockedList: TList;

begin

Result := 0;

LockedList := FCachedList.LockList;

try

Result := LockedList.Count;

finally

FCachedList.UnlockList;

end;

end;

function TObjectPool.GetLockObjCount: Integer;

var

LockedList: TList;

i:Integer;

begin

Result := 0;

LockedList := FCachedList.LockList;

try

for I := 0 to LockedList.Count - 1 do

begin

if TPoolItem(LockedList[I]).FLocked then Result := Result + 1;

end;

finally

FCachedList.UnlockList;

end;

end;

procedure TObjectPool.IniMinPools;

var

PoolsObject: TObject;

LockedList: TList;

I: Integer;

begin

LockedList := FCachedList.LockList;

try

for I := 0 to FMinCacheSize - 1 do

begin

PoolsObject := CreateObject;

if Assigned(PoolsObject) then

LockedList.Add(TPoolItem.Create(PoolsObject,False));

end;

finally

FCachedList.UnlockList;

end;

end;

function TObjectPool.LockObject: TObject;

var

LockedList: TList;

I: Integer;

begin

Result := nil;

LockedList := FCachedList.LockList;

try

Inc(FRequestCount);

for i := 0 to LockedList.Count - 1 do

begin

if not TPoolItem(LockedList.Items[i]).FLocked then

begin

Result := TPoolItem(LockedList.Items[i]).FInstance;

TPoolItem(LockedList.Items[i]).FLocked := True;

TPoolItem(LockedList.Items[i]).FLastTime := Now;

Inc(FCacheHit);//从池中取的次数

Break;

end;

end;

//

if not Assigned(Result) then

begin

Result := CreateObject;

//Assert(Assigned(Result));

Inc(FCreationCount);

if LockedList.Count < FMaxCacheSize then //池子容量

LockedList.Add(TPoolItem.Create(Result,True));

end;

finally

FCachedList.UnlockList;

end;

end;

procedure TObjectPool.OnMyTimer(Sender: TObject);

var

i:Integer;

LockedList: TList;

begin

LockedList := FCachedList.LockList;

try

for I := LockedList.Count - 1 downto 0 do

begin

if MyMinutesBetween(Now,TPoolItem(LockedList.Items[i]).FLastTime) >= FHourInterval * MinsPerHour then //释放池子许久不用的ADO

begin

TPoolItem(LockedList.Items[i]).Free;

LockedList.Delete(I);

end;

end;

finally

FCachedList.UnlockList;

end;

end;

procedure TObjectPool.SetFHourInterval(iValue: Integer);

begin

if iValue <= 1 then Exit;

if FHourInterval = iValue then Exit;

FTimer.Enabled := False;

try

FHourInterval := iValue;

FTimer.Interval := MSecsPerMins * MinsPerHour * FHourInterval;

finally

FTimer.Enabled := True;

end;

end;

procedure TObjectPool.StartAutoFree;

begin

if not FTimer.Enabled then FTimer.Enabled := True;

end;

procedure TObjectPool.StopAutoFree;

begin

if FTimer.Enabled then FTimer.Enabled := False;

end;

procedure TObjectPool.UnlockObject(Instance: TObject);

var

LockedList: TList;

I: Integer;

Item: TPoolItem;

begin

LockedList := FCachedList.LockList;

try

Item := nil;

for i := 0 to LockedList.Count - 1 do

begin

Item := TPoolItem(LockedList.Items[i]);

if Item.FInstance = Instance then

begin

Item.FLocked := False;

Item.FLastTime := Now;

Break;

end;

end;

if not Assigned(Item) then Instance.Free;

finally

FCachedList.UnlockList;

end;

end;

// 基于标准模板定义的泛型模板

{ TObjectPool<T> }

constructor TObjectPool<T>.Create(const MaxPools, MinPools: Integer);

begin

inherited Create(T,MaxPools,MinPools);

end;

function TObjectPool<T>.LockObject: T;

begin

Result := T(inherited LockObject);

end;

end.

// 基于泛型模板定义的具体模板

var

FQueryMgr:TObjectPool<TUniQuery>; //Query池子

FDspMgr:TObjectPool<TDataSetProvider>;//DSP池子

FCDSMgr:TObjectPool<TClientDataSet>;//cds池子

FDSMgr :TObjectPool<TDataSource>;//ds池子

FUniSQLMgr:TObjectPool<TUniSQL>;//执行SQL池子

FUniSPMgr :TObjectPool<TUniStoredProc>;//存储过程池子

// 创建具体模板

function QueryMgr:TObjectPool<TUniQuery>;

begin

if not Assigned(FQueryMgr) then

FQueryMgr := TObjectPool<TUniQuery>.Create(1000,20);

Result := FQueryMgr;

end;

http://www.vckbase.com/module/articleContent.php?id=4386

时间: 2024-10-02 22:42:33

delphi新语法之泛型实现的对象池模板的相关文章

class helper 可能是从 Delphi 2007 增加的新语法

class helper 可能是从 Delphi 2007 增加的新语法, 因为感觉不太实用, 直到今天才测试了一下. 试过之后才知道: 挺有意思的! 基本功能就是修改已存在的类. Txxx = class helper for T... {T... 表示已存在的类} {可以替换已存在的方法} {也可以有新的方法.成员}end;//这之后再使用 T... 类及其子孙类时, 都会优先使用 Txxx 的修改. 例一: unit Unit1;interfaceuses Windows, Message

.NET中那些所谓的新语法之三:系统预定义委托与Lambda表达式

开篇:在上一篇中,我们了解了匿名类.匿名方法与扩展方法等所谓的新语法,这一篇我们继续征程,看看系统预定义委托(Action/Func/Predicate)和超爱的Lambda表达式.为了方便码农们,.Net基类库针对实际开发中最常用的情形提供了几个预定义好的委托,这些委托可以直接使用,无需再重头定义一个自己的委托类型.预定义委托在.Net基类库中使用的比较广泛,比如在Lambda表达式和并行计算中都大量地使用,需要我们予以关注起来! /* 新语法索引 */ 1.自动属性 Auto-Impleme

.NET中那些所谓的新语法之四:标准查询运算符与LINQ

开篇:在上一篇中,我们了解了预定义委托与Lambda表达式等所谓的新语法,这一篇我们继续征程,看看标准查询运算符和LINQ.标准查询运算符是定义在System.Linq.Enumerable类中的50多个为IEnumerable<T>准备的扩展方法,而LINQ则是一种类似于SQL风格的查询表达式,它们可以大大方便我们的日常开发工作.因此,需要我们予以关注起来! /* 新语法索引 */ 1.自动属性 Auto-Implemented Properties 2.隐式类型 var 3.参数默认值 和

Java 8 新特性之泛型的类型推导

1. 泛型究竟是什么? 在讨论类型推导(type inference)之前,必须回顾一下什么是泛型(Generic).泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.通俗点将就是“类型的变量”.这种类型变量可以用在类.接口和方法的创建中.理解Java泛型最简单的方法是把它看成一种便捷语法,能节省你某些Java类型转换(casting)上的操作: List<Apple> box = new ArrayList<Apple>();

.NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法

开篇:在上一篇中,我们了解了自动属性.隐式类型.自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类.匿名方法以及常用的扩展方法.虽然,都是很常见的东西,但是未必我们都明白其中蕴含的奥妙.所以,跟着本篇的步伐,继续来围观. /* 新语法索引 */ 1.自动属性 Auto-Implemented Properties 2.隐式类型 var 3.参数默认值 和 命名参数 4.对象初始化器 与 集合初始化器 { } 5.匿名类 & 匿名方法 6.扩展方法 7.系统内置委托 Func / Acti

.NET中那些所谓的新语法之一:自动属性、隐式类型、命名参数与自动初始化器

开篇:在日常的.NET开发学习中,我们往往会接触到一些较新的语法,它们相对以前的老语法相比,做了很多的改进,简化了很多繁杂的代码格式,也大大减少了我们这些菜鸟码农的代码量.但是,在开心欢乐之余,我们也不禁地对编译器内部到底为我们做了哪些事儿而感到好奇?于是,我们就借助反编译神器,去看看编译器到底做了啥事!其实本篇中很多都不算新语法,对于很多人来说可能都是接触了很久了,这里主要是针对.NET的老版本来说,是一个“相对”的新语法. /* 新语法索引 */ 1.自动属性 Auto-Implemente

总结常见的ES6新语法特性。

前言 ES6是即将到来的新版本JavaScript语言的标准,他给我们带来了更"甜"的语法糖(一种语法,使得语言更容易理解和更具有可读性,也让我们编写代码更加简单快捷),如箭头函数(=>).class等等.用一句话来说就是: ES6给我们提供了许多的新语法和代码特性来提高javascript的体验 不过遗憾的是,现在还没有浏览器能够很好的支持es6语法,点这里查看浏览器支持情况,所以我们在开发中还需要用babel进行转换为CommonJS这种模块化标准的语法. 因为下面我会讲到一

【JavaSE】day04_Collection_Iterator_新循环_泛型

1.Collection集合的批量操作 1)boolean addAll(Collection c) 将给定的集合中的所有元素添加到当前集合中. 当执行完毕后,当前集合中的元素发生改变则返回true. 2)boolean containsAll(Collection c) 判断当前集合中是否包含给定集合里的所有元素,全部包含则返回true. 这里判断的依据依然是依靠元素的equals比较的. 代码演示: package day04; import java.util.ArrayList; imp

C#7的新语法

C#7为C#语言添加了许多新功能: out变量: 您可以将out内联值声明为使用它们的方法的参数. 元组 您可以创建包含多个公共字段的轻量级,未命名的类型.编译器和IDE工具可以理解这些类型的语义. 模式匹配 您可以根据这些类型的成员的任意类型和值创建分支逻辑. ref 当地人和回报 方法参数和局部变量可以是对其他存储的引用. 本地功能 您可以将功能嵌套在其他功能中,以限制其范围和可见性. 更健康的成员 可以使用表达式创作的成员列表已经增加. throw 表达式 您可以在以前不允许的代码结构中抛