2011年4月14日

DelphiでSingletonパターンを実装する(Monitor版)

前回の実装のなかで、CriticalSectionを使用して排他をかけるもの(Unit12)がありましたが、Delphi 2009の新機能のなかにMonitor (ja)という同期メカニズムがあります。そこでCriticalSectionのかわりにMonitorを使用したバージョンを作ってみました。

unit Unit18;

interface

uses
  SysUtils;

type
  TSingleton = class(TObject)
  private
    FTestValue: Integer;
    class var
      FSingleton: TSingleton;
      FLock: TObject;
    constructor CreateInstance;
  public
    class constructor Create;
    class destructor  Destroy;
    constructor Create;
    destructor  Destroy; override;
    class function GetInstance: TSingleton;
    property    TestValue: Integer
                  read  FTestValue
                  write FTestValue;
  end;

  ECreateSingleton = class(Exception)
  end;


implementation

{ TSingleton }

class constructor TSingleton.Create;
begin

  FSingleton := nil;
  FLock := TObject.Create;

end;

class destructor TSingleton.Destroy;
begin

  FLock.Free;
  FSingleton.Free;

end;

constructor TSingleton.Create;
begin

  raise ECreateSingleton.Create('TSingleton.Create cannot use.');

end;

constructor TSingleton.CreateInstance;
begin

  inherited Create;

  { Initialize }
  FTestValue := 0;

end;

destructor TSingleton.Destroy;
begin

  { Finalize }

  inherited;

end;

class function TSingleton.GetInstance: TSingleton;
begin

  System.TMonitor.Enter(FLock);
  try
    if FSingleton = nil then
    begin
      FSingleton := TSingleton.CreateInstance;
    end;

  finally
    System.TMonitor.Exit(FLock);
  end;

  Result := FSingleton;

end;

end.

元ねたは

What is TMonitor in Delphi System unit good for? - Stack Overflow
Monitor (synchronization) - Wikipedia, the free encyclopedia (ja)
Craig Stuntz’s Weblog : Why Has the Size of TObject Doubled In Delphi 2009?
The Oracle at Delphi » Simmering Unicode, bring DPL to a boil
The Oracle at Delphi » Simmering Unicode, bring DPL to a boil (Part 2)
The Oracle at Delphi » Breaking the rules

あたり。System.TMonitorの詳しい説明とかサンプルはないんでしょうか?

2011/04/15追記: .NET FrameworkのMonitorクラスの説明が参考になりそうです。

Monitor クラス (System.Threading)

実装例は第15回 エンバカデロ・デベロッパーキャンプの【A5】Delphi/C++テクニカルセッション「詳説!DataSnap 2010」のコネクションプーリングの実装あたりでしょうか(高橋さん、いつも情報ありがとうございます)。

3 件のコメント:

高橋智宏 さんのコメント...

.NETのMonitorをDelphi(Win32)にマッピングしたものですが、docwikiの関数リストではどうですか?
http://docwiki.embarcadero.com/VCL/ja/System.TMonitor_Functions

高橋智宏 さんのコメント...

第15回 エンバカデロ・デベロッパーキャンプ

【A5】Delphi/C++テクニカルセッション「詳説!DataSnap 2010」
http://conferences.embarcadero.com/article/images/40256/a5.pdf
で、System.TMonitorの使用例(コネクションプーリング実装)を書いています。

ふー さんのコメント...

ヘルプ(docwiki)の説明は…個々の関数の説明はあれでもよいのでしょうけど、あれを見てTMonitorを使おうという判断はちょっと難しいように思います。Allen Bauerさんの説明だとCriticalSectionを使うところには等価で置き換えられる、ということですが、じゃあ何が違ってTMonitorのどこがいいのか、といったところが不足かな、と。
デベロッパーキャンプのサンプルは、そもそもこのアーティクル(TMonitor版)を書こうと思ったきっかけなのです。