对象池一般在服务端使用,所以稳定性是第一的。

欢迎提意见

unit uMyObjectPool;

interface

uses
SyncObjs, Classes, Windows, SysUtils; type
TObjectBlock = record
private
FObject:TObject;
FUsing:Boolean;
FBorrowTime:Cardinal; //借出时间
FRelaseTime:Cardinal; //归还时间
end; PObjectBlock = ^TObjectBlock; TMyObjectPool = class(TObject)
private
FObjectClass:TClass; FLocker: TCriticalSection; //全部归还信号
FReleaseSingle: THandle; //有可用的对象信号灯
FUsableSingle: THandle; FMaxNum: Integer; /// <summary>
/// 正在使用的对象列表
/// </summary>
FBusyList:TList; /// <summary>
/// 可以使用的对象列表
/// </summary>
FUsableList:TList; FName: String;
FTimeOut: Integer; procedure makeSingle;
function GetCount: Integer;
procedure lock;
procedure unLock;
protected
/// <summary>
/// 清理空闲的对象
/// </summary>
procedure clear; /// <summary>
/// 创建一个对象
/// </summary>
function createObject: TObject; virtual;
public
constructor Create(pvObjectClass: TClass = nil);
destructor Destroy; override; /// <summary>
/// 重置对象池
/// </summary>
procedure resetPool; /// <summary>
/// 借用一个对象
/// </summary>
function borrowObject: TObject; /// <summary>
/// 归还一个对象
/// </summary>
procedure releaseObject(pvObject:TObject); /// <summary>
/// 获取正在使用的个数
/// </summary>
function getBusyCount:Integer; //等待全部还回
function waitForReleaseSingle: Boolean; /// <summary>
/// 等待全部归还信号灯
/// </summary>
procedure checkWaitForUsableSingle; /// <summary>
/// 当前总的个数
/// </summary>
property Count: Integer read GetCount; /// <summary>
/// 最大对象个数
/// </summary>
property MaxNum: Integer read FMaxNum write FMaxNum; /// <summary>
/// 对象池名称
/// </summary>
property Name: String read FName write FName; /// <summary>
/// 等待超时信号灯
/// 单位毫秒
/// </summary>
property TimeOut: Integer read FTimeOut write FTimeOut;
end; implementation procedure TMyObjectPool.clear;
var
lvObj:PObjectBlock;
begin
lock;
try
while FUsableList.Count > do
begin
lvObj := PObjectBlock(FUsableList[FUsableList.Count-]);
lvObj.FObject.Free;
FreeMem(lvObj, SizeOf(TObjectBlock));
FUsableList.Delete(FUsableList.Count-);
end;
finally
unLock;
end;
end; constructor TMyObjectPool.Create(pvObjectClass: TClass = nil);
begin
inherited Create;
FObjectClass := pvObjectClass; FLocker := TCriticalSection.Create();
FBusyList := TList.Create;
FUsableList := TList.Create; //默认可以使用5个
FMaxNum := ; //等待超时信号灯 秒
FTimeOut := * ; //
FUsableSingle := CreateEvent(nil, True, True, nil); //创建信号灯,手动控制
FReleaseSingle := CreateEvent(nil, True, True, nil); makeSingle;
end; function TMyObjectPool.createObject: TObject;
begin
Result := nil;
if FObjectClass <> nil then
begin
Result := FObjectClass.Create;
end;
end; destructor TMyObjectPool.Destroy;
begin
waitForReleaseSingle;
clear;
FLocker.Free;
FBusyList.Free;
FUsableList.Free; CloseHandle(FUsableSingle);
CloseHandle(FReleaseSingle);
inherited Destroy;
end; function TMyObjectPool.getBusyCount: Integer;
begin
Result := FBusyList.Count;
end; { TMyObjectPool } procedure TMyObjectPool.releaseObject(pvObject:TObject);
var
i:Integer;
lvObj:PObjectBlock;
begin
lock;
try
for i := to FBusyList.Count - do
begin
lvObj := PObjectBlock(FBusyList[i]);
if lvObj.FObject = pvObject then
begin
FUsableList.Add(lvObj);
lvObj.FRelaseTime := GetTickCount;
FBusyList.Delete(i);
Break;
end;
end; makeSingle;
finally
unLock;
end;
end; procedure TMyObjectPool.resetPool;
begin
waitForReleaseSingle; clear;
end; procedure TMyObjectPool.unLock;
begin
FLocker.Leave;
end; function TMyObjectPool.borrowObject: TObject;
var
i:Integer;
lvObj:PObjectBlock;
lvObject:TObject;
begin
Result := nil; while True do
begin
//是否有可用的对象
checkWaitForUsableSingle;
////如果当前有1个可用,线程同时借用时,都可以直接进入等待成功。 lock;
try
lvObject := nil;
if FUsableList.Count > then
begin
lvObj := PObjectBlock(FUsableList[FUsableList.Count-]);
FUsableList.Delete(FUsableList.Count-);
FBusyList.Add(lvObj);
lvObj.FBorrowTime := getTickCount;
lvObj.FRelaseTime := ;
lvObject := lvObj.FObject;
end else
begin
if GetCount >= FMaxNum then
begin
//如果当前有1个可用,线程同时借用时,都可以直接(checkWaitForUsableSingle)成功。
continue;
//退出(unLock)后再进行等待....
//raise exception.CreateFmt('超出对象池[%s]允许的范围[%d]', [self.ClassName, FMaxNum]);
end;
lvObject := createObject;
if lvObject = nil then raise exception.CreateFmt('不能得到对象,对象池[%s]未继承处理createObject函数', [self.ClassName]); GetMem(lvObj, SizeOf(TObjectBlock));
try
ZeroMemory(lvObj, SizeOf(TObjectBlock)); lvObj.FObject := lvObject;
lvObj.FBorrowTime := GetTickCount;
lvObj.FRelaseTime := ;
FBusyList.Add(lvObj);
except
lvObject.Free;
FreeMem(lvObj, SizeOf(TObjectBlock));
raise;
end;
end; //设置信号灯
makeSingle; Result := lvObject;
//获取到
Break;
finally
unLock;
end;
end;
end; procedure TMyObjectPool.makeSingle;
begin
if (GetCount < FMaxNum) //还可以创建
or (FUsableList.Count > ) //还有可使用的
then
begin
//设置有信号
SetEvent(FUsableSingle);
end else
begin
//没有信号
ResetEvent(FUsableSingle);
end; if FBusyList.Count > then
begin
//没有信号
ResetEvent(FReleaseSingle);
end else
begin
//全部归还有信号
SetEvent(FReleaseSingle)
end;
end; function TMyObjectPool.GetCount: Integer;
begin
Result := FUsableList.Count + FBusyList.Count;
end; procedure TMyObjectPool.lock;
begin
FLocker.Enter;
end; function TMyObjectPool.waitForReleaseSingle: Boolean;
var
lvRet:DWORD;
begin
Result := false;
lvRet := WaitForSingleObject(FReleaseSingle, INFINITE);
if lvRet = WAIT_OBJECT_ then
begin
Result := true;
end;
end; procedure TMyObjectPool.checkWaitForUsableSingle;
var
lvRet:DWORD;
begin
lvRet := WaitForSingleObject(FUsableSingle, FTimeOut);
if lvRet <> WAIT_OBJECT_ then
begin
raise Exception.CreateFmt('对象池[%s]等待可使用对象超时(%d),使用状态[%d/%d]!',
[FName, lvRet, getBusyCount, FMaxNum]);
end;
end; end.

Delphi对象池MyObjectPool.pas的更多相关文章

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

    现在的DELPHI因为支持泛型的语法,所以也能支持模板编程了.   // 标准模板 unit UntPools;   interface   uses   Classes, SysUtils, Unt ...

  2. 论DATASNAP中间件对象池

    在此,笔者以DATASNAP为例,其它中间件以此类推. 中间件为什么要使用对象池? 对象池——让所有的对象免堕轮回之苦,对象不再为其生和死而烦恼. 要想让中间件长久稳定地运行,做到无人值守,对象池很重 ...

  3. Java 中的对象池实现

    点赞再看,动力无限.Hello world : ) 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. 最近在 ...

  4. 设计模式之美:Object Pool(对象池)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):实现 DatabaseConnectionPool 类. 实现方式(二):使用对象构造方法和预分配方式实现 ObjectPool ...

  5. Egret中的对象池ObjectPool

    为了可以让对象复用,防止大量重复创建对象,导致资源浪费,使用对象池来管理. 对象池具体含义作用,自行百度. 一 对象池A 二 对象池B 三 字符串key和对象key的效率 一 对象池A /** * 对 ...

  6. 对象池与.net—从一个内存池实现说起

    本来想写篇关于System.Collections.Immutable中提供的ImmutableList里一些实现细节来着,结果一时想不起来源码在哪里--为什么会变成这样呢--第一次有了想写分析的源码 ...

  7. 通用对象池ObjectPool的一种简易设计和实现方案

    对象池,最简单直接的作用当然是通过池来减少创建和销毁对象次数,实现对象的缓存和复用.我们熟知的线程池.数据库连接池.TCP连接池等等都是非常典型的对象池. 一个基本的简易对象池的主要功能实现我认为应该 ...

  8. paip.提升性能----数据库连接池以及线程池以及对象池

    paip.提升性能----数据库连接池以及线程池以及对象池 目录:数据库连接池c3po,线程池ExecutorService:Jakartacommons-pool对象池 作者Attilax  艾龙, ...

  9. common-pool2对象池(连接池)的介绍及使用

    我们在服务器开发的过程中,往往会有一些对象,它的创建和初始化需要的时间比较长,比如数据库连接,网络IO,大数据对象等.在大量使用这些对象时,如果不采用一些技术优化,就会造成一些不可忽略的性能影响.一种 ...

随机推荐

  1. TP3.2框架,实现空模块、空控制器、空操作的页面404替换||同步实现apache报错404页面替换

    一,前言 一.1)以下代码是在TP3.0版本之后,URL的默认模式=>PATHINFO的前提下进行的.(通俗点,URL中index.php必须存在且正确) 代码和讲解如下: 1.空模块解决:ht ...

  2. Delphi单元文件引用名称问题

    Delphi新版本的单元文件格式变化了,如windows变成了winapi.windows,如果想在单元引用中使用简称,则需要在工程选项中配置: 这样就可以使用全名或简写来引用单元了.

  3. C语言字符串

    C语言字符串 一.字符串基础 注意:字符串一定以\0结尾. Printf(“yang\n”); 其中yang为字符串常量,“yang”=‘y’+‘a’+‘n’+‘g’+‘\0’.字符串由很多的字符组成 ...

  4. 一台电脑存放多个git账户的多个rsa秘钥(转)

    如何在一个电脑上存储多个git账户生成的多份rsa秘钥,实现多个账户同时使用配置的情况?今天,不幸又再次遇到这个问题. 问题描述 公司最近在开发一款开源产品,项目被托管在github上,但是公司内部一 ...

  5. Magento模块升级修改数据库表结构

    Magento支持在模块中创建.删除.更新数据库表及字段.通过该方式,在插件开发的过程中,添加和修改字段变成了一件非常轻松的事情.只需要修改模块的版本号,同时在文件中添加一个符合命名规则的脚本就可以了 ...

  6. 【SqlServer】T-SQL的简介及基本用法

    一.T-SQL概述 SQL Server用于操作数据库的编程语言为Transaction-SQL,简称T-SQL.T-SQL与PL/SQL不同,并没有固定的程序结构.T-SQL包括以下4个部分: DD ...

  7. 【Linux】分割命令split

    如果你有文件太大,导致一些携带式装置无法复制的问题,嘿嘿!找 split 就对了! 他可以帮你将一个大文件,依据文件大小或行数来分割,就可以将大文件分割成为小文件了! 快速又有效啊!真心不错- [ro ...

  8. 如何检查后台服务(Android的Service类)是否正在运行?

    private boolean isServiceRunning() { ActivityManager manager = (ActivityManager) getSystemService(AC ...

  9. Oracle 12C -- Invisible Columns

    在12C中,当一个列被定义为"不可见"的时候,没有直接访问该列的sql语句是无法看到"不可见列"的,显式引用"不可见列"的语句是可以访问和操 ...

  10. C++编程技巧降低编译时间

    1. #define的保护 全部头文件都应该使用#define 防止头文件被多重包括(multiple inclusion).命名格式 当是:<PROJECT>_<PATH>_ ...