博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Delphi 线程安全单例
阅读量:6414 次
发布时间:2019-06-23

本文共 5167 字,大约阅读时间需要 17 分钟。

在C++中写了一个多线程环境下写日志的插件,考虑到以前写Delphi代码时对文件的操作类封装时老是欠缺线程安全方面的考虑,所以总结了一下,写了一个线程安全的单例。可能有欠缺之处请各位朋友多多指教。
首先自己封了一个多线程的临界操作类,用来管理多线程的临界区,方法很简单只是单独对WINDOWS API的封装,实现单元如下:
(*******************************************************************
*@file: CriticalSectionU.pas
*@desc: 多线程操作时,对临界区的封装
*@author: daihw
*@date: 2009-03-03
*******************************************************************)
unit CriticalSectionU;
interface
uses Windows,Classes,CommCtrl,Dialogs;
type
    TMCriticalSection=class(TObject)
   protected
     FCriticalSection:TRTLCriticalSection;
   public
     constructor create;
     destructor destory;
     function Init():TRTLCriticalSection; 
     function lock():Boolean; 
     function unlock():Boolean;
     function Trim():Boolean;
   end;
   TMAutoCriticalSection=class(TMCriticalSection)
   public
     constructor Create;
     destructor Destory;
   end;
   TMsafeDeleteCriticalSection=class(TMCriticalSection)
   private
     m_bInitialized:Boolean; 
   public
     constructor Create;
     destructor Destory ;
     function Init():TRTLCriticalSection;
     function lock():Boolean;
     function unlock():Boolean;
     function Trim():Boolean;
   end;
implementation
{ TMCriticalSection }
constructor TMCriticalSection.create;
begin
InitializeCriticalSection(FCriticalSection);
end;
destructor TMCriticalSection.destory;
begin
   DeleteCriticalSection(FcriticalSection);
end;
function TMCriticalSection.Init: TRTLCriticalSection;
begin
     RESULT := FCriticalSection;
end;
function TMCriticalSection.lock: Boolean;
begin
EnterCriticalSection(FCriticalSection);
Result:=true;
end;
function TMCriticalSection.Trim: Boolean;
begin
DeleteCriticalSection(FcriticalSection);
Result:=true;
end;
function TMCriticalSection.unlock: Boolean;
begin
LeaveCriticalSection(FcriticalSection);
Result:=true; 
end;
{ TMAutoCriticalSection }
constructor TMAutoCriticalSection.Create;
begin
inherited Create;
end;
destructor TMAutoCriticalSection.Destory;
begin
inherited Destory;
end;
{ TMsafeDeleteCriticalSection }
constructor TMsafeDeleteCriticalSection.Create;
begin
inherited Create;
m_bInitialized:=True;
end;
destructor TMsafeDeleteCriticalSection.Destory;
begin
m_bInitialized:=False;
inherited Destory; 
end;
function TMsafeDeleteCriticalSection.Init: TRTLCriticalSection;
begin
if (m_bInitialized) then
Result:=Init; 
end;
function TMsafeDeleteCriticalSection.lock: Boolean;
begin
if (m_bInitialized) then
    Result:= inherited lock
else
    Result:=False;
end;
function TMsafeDeleteCriticalSection.Trim: Boolean;
begin
if (m_bInitialized) then
     Result:= inherited Trim
else
     Result:=False;
end;
function TMsafeDeleteCriticalSection.unlock: Boolean;
begin
if (m_bInitialized) then
     Result:= inherited unlock
else
     Result:=true; 
end;
end.
做好临界处理后,开始实现线程安全的单例对象,实现代码如下:
(*******************************************************************
*@file: singletonU.pas
*@desc: 线程安全的单例,通过引用计数维护对象生命周期.
*@author: daihw
*@date: 2009-03-03
*******************************************************************)
unit SingletonU;
interface
uses Classes, SysUtils, CommCtrl, Dialogs, Windows, CriticalSectionU;
type
TDSingletonCreator = class(TObject)
private
    FMsg: string;
public
    property Msg: string read FMsg write FMsg;
    class function Instance(): TDSingletonCreator;
    class function Release(): Integer;
    class function NewInstance: TObject; override;
    procedure FreeInstance; override;
end;
implementation
var
_sc: TMsafeDeleteCriticalSection = nil;
_self: TDSingletonCreator = nil;
_refCount: LongInt = 0;
{ TDSingleton }
procedure TDSingletonCreator.FreeInstance;
begin
inherited;
_sc := nil;
_self := nil;
end;
class function TDSingletonCreator.Instance: TDSingletonCreator;
begin
if not Assigned(_sc) then
begin
    _sc := TMsafeDeleteCriticalSection.create();
end;
_sc.lock();
if not Assigned(_self) then
    _self := TDSingletonCreator.create;
_sc.unlock();
Inc(_refCount);
Result := _self;
end;
class function TDSingletonCreator.NewInstance: TObject;
begin
if not Assigned(_sc) then
begin
    _sc := TMsafeDeleteCriticalSection.create();
end;
_sc.lock();
if not Assigned(_self) then
    _self := TDSingletonCreator(inherited NewInstance);
_sc.unlock();
Inc(_refCount);
Result := _self;
end;
class function TDSingletonCreator.Release: Integer;
begin
if Assigned(_sc) then
begin
    _sc.lock();
    if (_refCount = 0) then
      Result := 0;
    Dec(_refCount);
    if (_refCount = 0) then
      if Assigned(_self) then
        FreeAndNil(_self);
    _sc.unlock();
    if (_refCount = 0) then
      FreeAndNil(_sc);
    Result := _refCount;
end
else
    Result := 0;
end;
end.
测试代码如下:
unit TestU;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
    btn1: TButton;
    btn2: TButton;
    procedure btn1Click(Sender: TObject);
    procedure btn2Click(Sender: TObject);
private
    { Private declarations }
public
    { Public declarations }
end;
var
Form1: TForm1;
implementation
uses
SingletonU;
{$R *.dfm}
procedure TForm1.btn1Click(Sender: TObject);
var
singleton:TDSingletonCreator;
begin
singleton:=TDSingletonCreator.Instance;
singleton.Msg:='121212';
TDSingletonCreator.Release;
end;
procedure TForm1.btn2Click(Sender: TObject);
var
singleton:TDSingletonCreator;
begin
singleton:=TDSingletonCreator.Create;
ShowMessage(singleton.msg);
singleton.Free;  
end;
end.
总结:这片文章写出来可能对多线程环境下文件操作,有点帮助,比如:日志文件的读写操作。

转载地址:http://smbra.baihongyu.com/

你可能感兴趣的文章
HDU Problem 4907 Take schedule 【二分】
查看>>
注解@Slf4j的作用
查看>>
linux 文件操作与目录操作
查看>>
解决IE6浏览器下position:fixed固定定位问题
查看>>
KMP串匹配算法解析与优化
查看>>
css3动画简介以及动画库animate.css的使用
查看>>
javascript DOM节点操作
查看>>
c++ invoke java in android
查看>>
meta 之 viewport
查看>>
Linux下文件 ~/.bashrc 和 ~/.bash_profile 和 /etc/bashrc 和 /etc/profile 的区别 | 用户登录后加载配置文件的顺序...
查看>>
关于在swiper轮播组件中使用echarts的'click'事件无效
查看>>
Android开源项目README规范
查看>>
asp.net core 教程(五)-配置
查看>>
Spring Bean Scope (作用域)
查看>>
Redis命令操作详解
查看>>
c++ map: 使用struct或者数组做value
查看>>
列表中的陷阱
查看>>
算法-无重复字符的最长子串
查看>>
java.lang.ClassNotFoundException: org.apache.axis2.transport.http.AxisAdminServlet
查看>>
SSL协议详解
查看>>