多线程 – 在Delphi中读取TList线程是否安全?

前端之家收集整理的这篇文章主要介绍了多线程 – 在Delphi中读取TList线程是否安全?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经构建了一个简单的日志记录类,并希望确认它是线程安全的.基本上,将从不同的线程调用Log,RegisterLogger和UnRegisterLogger.日志将很少被调用(来自许多不同的线程)和RegisterLogger和UnRegisterLogger很少.

基本上我的问题可归结为:“读取TList< x>线程是否安全?”,也就是说我可以让多个线程同时访问TList.

IExecutionCounterLogger是一个带有Log方法的接口(与TExecutionCounterServer.Log具有相同的签名)

Type
  TExecutionCounterServer = class
  private
    Loggers : TList<IExecutionCounterLogger>;
    Synchronizer : TMultiReadExclusiveWriteSynchronizer;
  public
    procedure RegisterLogger(Logger : IExecutionCounterLogger);
    procedure UnRegisterLogger(Logger : IExecutionCounterLogger);
    procedure Log(const ClassName,MethodName : string; ExecutionTime_ms : integer);

    constructor Create;
    destructor Destroy; override;
  end;

constructor TExecutionCounterServer.Create;
begin
  Loggers := TList<IExecutionCounterLogger>.Create;
  Synchronizer := TMultiReadExclusiveWriteSynchronizer.Create;
end;

destructor TExecutionCounterServer.Destroy;
begin
  Loggers.Free;
  Synchronizer.Free;
  inherited;
end;

procedure TExecutionCounterServer.Log(const ClassName,MethodName: string; ExecutionTime_ms: integer);
var
  Logger: IExecutionCounterLogger;
begin
  Synchronizer.BeginRead;
  try
    for Logger in Loggers do
      Logger.Log(ClassName,MethodName,ExecutionTime_ms);
  finally
    Synchronizer.EndRead;
  end;
end;

procedure TExecutionCounterServer.RegisterLogger(Logger: IExecutionCounterLogger);
begin
  Synchronizer.BeginWrite;
  try
    Loggers.Add(Logger);
  finally
    Synchronizer.EndWrite;
  end;
end;

procedure TExecutionCounterServer.UnRegisterLogger(Logger: IExecutionCounterLogger);
var
  i : integer;
begin
  Synchronizer.BeginWrite;
  try
    i := Loggers.IndexOf(Logger);
    if i = -1 then
      raise Exception.Create('Logger not present');
    Loggers.Delete(i);  
  finally
    Synchronizer.EndWrite;
  end;
end;

作为更多背景,这是从this question开始的.我基本上已经为(DCOM)DataSnap服务器的每个方法添加了一些工具,我也已经连接到每个TDataSnapProvider OnGetData和OnUpdateData事件.

解决方法

Are reads on TList<T> thread safe? That is to say can I have multiple threads accessing a TList<T> at the same time?

这是线程安全的,不需要同步.多个线程可以安全地同时读取.这相当于(并且实际上实现为)从数组中读取.只有当您的某个线程修改了需要同步的列表时.

您的代码比此方案稍微复杂一些.您似乎需要满足修改列表的线程.但是你已经使用TMultiReadExclusiveWriteSynchronizer这样做了,这是一个非常好的解决方案.它允许多个读取线程同时操作,但任何写入线程都相对于所有其他线程进行序列化.

原文链接:https://www.f2er.com/java/121883.html

猜你在找的Java相关文章