现在的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

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

  1. Delphi新语法 For ..In

    首先我们要知道哪些类型可以用For In吧,下面就是: for Element in ArrayExpr do Stmt;      数组 for Element in StringExpr do S ...

  2. Delphi新语法

    http://www.cnblogs.com/hnxxcxg/category/456344.html

  3. 关于C#7 新语法糖

    C#7新语法糖 1.Switch 使用  goto 使用 ; switch (kk) { : Console.WriteLine(); ; : Console.WriteLine(); ; : Con ...

  4. Delphi 7以来的Delphi 2009测试版新语法特性

    我晕,Delphi 7 以后增加了这么多有用的语法,我都不知道.真是越学越觉得自己浅薄,自己所作的Delphi项目所用的知识还不够Delphi知识储备体系的十分之一,更别说Delphi还在继续发展. ...

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

    class helper 可能是从 Delphi 2007 增加的新语法, 因为感觉不太实用, 直到今天才测试了一下. 试过之后才知道: 挺有意思的! 基本功能就是修改已存在的类. Txxx = cl ...

  6. 2. 现代 javascript 新语法 及 对象专题

    let , const 和 var javascript 里面的作用域 一个大括号 是一个作用域 {  } var 会 在局部作用定义 被定义时 会提升作用域  如 if 的 {} 就属于 局部作用域 ...

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

    1. 泛型究竟是什么? 在讨论类型推导(type inference)之前,必须回顾一下什么是泛型(Generic).泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据 ...

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

    开篇:在上一篇中,我们了解了自动属性.隐式类型.自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类.匿名方法以及常用的扩展方法.虽然,都是很常见的东西,但是未必我们都明白其中蕴含的奥妙.所以, ...

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

    开篇:在上一篇中,我们了解了匿名类.匿名方法与扩展方法等所谓的新语法,这一篇我们继续征程,看看系统预定义委托(Action/Func/Predicate)和超爱的Lambda表达式.为了方便码农们,. ...

随机推荐

  1. 使用VIM + Ctags

    通常在Linux或其他*Nix环境我们都使用VIM作为代码编辑工具,在纯命令终端下,它几乎是无可替代的. 它具有非常强大的扩展机制,在文字编辑方面基本上无所不能. 不过Emacs用户请不要激动,笔者还 ...

  2. js 保留两位小数

    1. 最笨的办法....... function get() { var s = 22.127456 + ""; var str = s.substring(0,s.indexOf ...

  3. [转载] 高大上的 CSS 效果:Shape Blobbing

    这篇大部分是转载,来自<高大上的 CSS 效果:Shape Blobbing>和 <Shape Blobbing in CSS> 有部分是自己理解和整理,配合效果要做出 app ...

  4. python-base64编码与解码

    base64编码原理: 例如: 实例一: #-*- coding: UTF-8 -*- ' __date__ = '2015/12/23' import base64 code = "aGV ...

  5. sshd服务---暴力破解应对策略

    sshd服务暴力破解步骤 sshd暴力破解方法 防止暴力破解调优 1. 变更默认端口 2. 变更root用户 3. 日志监控-->防止暴力破解(fail2ban应用) fail2ban详解 在初 ...

  6. 安卓linearlayout布局的一个嵌套实例

    XML代码如下 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andr ...

  7. JavaScript代码编写尝试使用Vanilla JS 或者Jquery插件

    From Here: http://vanilla-js.com/ Vanilla JS is a fast, lightweight, cross-platform frameworkfor bui ...

  8. Ignatius and the Princess II(全排列)

    Ignatius and the Princess II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K ( ...

  9. scanf 和cin 的区别

    笔试的时候经常遇到突然string s;cin>>s; 有的时候编译会错误,不知道为什么. 今天在练习枚举类型的时候,也遇到这样一个问题. enum weekday{Monday,Tues ...

  10. QF——iOS第三方登录和社会化分享

    QQ登录的流程: 1.下载SDK,并添加到项目中: 2.添加SDK需要的依赖库,以及配置文件: 3.重写APPDelegate的方法handleOpenURL和openURL: 4.实现Tencent ...