zoukankan      html  css  js  c++  java
  • Delphi 线程安全单例

    在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.

    总结:这片文章写出来可能对多线程环境下文件操作,有点帮助,比如:日志文件的读写操作。
  • 相关阅读:
    笔记35 跨重定向请求传递数
    判断邮箱的正则表达式
    按钮
    async await 的用法
    笔记34 Spring MVC的高级技术——处理multipart形式的数据
    Convert Sorted Array to Binary Search Tree
    Binary Tree Zigzag Level Order Traversal
    Unique Binary Search Trees,Unique Binary Search Trees II
    Validate Binary Search Tree
    Populating Next Right Pointers in Each Node,Populating Next Right Pointers in Each Node II
  • 原文地址:https://www.cnblogs.com/jxgxy/p/2085138.html
Copyright © 2011-2022 走看看