我一直在使用一些多线程应用程序,其中一部分需要线程保护对象。我使用以下方法对单个对象线程进行了保护:
type
TMyClass = class(TObject)
private
FLock: TRTLCriticalSection;
FSomeString: String;
procedure Lock;
procedure Unlock;
function GetSomeString: String;
procedure SetSomeString(Value: String);
public
constructor Create;
destructor Destroy; override;
property SomeString: String read GetSomeString write SetSomeString;
end;
implementation
constructor TMyClass.Create;
begin
InitializeCriticalSection(FLock);
Lock;
try
//Initialize some stuff
finally
Unlock;
end;
end;
destructor TMyClass.Destroy;
begin
Lock;
try
//Finalize some stuff
finally
Unlock;
end;
DeleteCriticalSection(FLock);
inherited Destroy;
end;
procedure TMyClass.Lock;
begin
EnterCriticalSection(FLock);
end;
procedure TMyClass.Unlock;
begin
LeaveCriticalSection(FLock);
end;
function TMyClass.GetSomeString: String;
begin
Result:= '';
Lock;
try
Result:= FSomeString;
finally
Unlock;
end;
end;
procedure TMyClass.SetSomeString(Value: String);
begin
Lock;
try
FSomeString:= Value;
finally
Unlock;
end;
end;
但是,当我实现一个对象列表时,我无法弄清楚如何安全地保护每个对象。我像这样创建我的对象列表:
type
TMyClass = class;
TMyClasses = class;
TMyClass = class(TObject)
private
FOwner: TMyClasses;
public
constructor Create(AOwner: TMyClasses);
destructor Destroy; override;
end;
TMyClasses = class(TObject)
private
FItems: TList;
function GetMyItem(Index: Integer): TMyItem;
public
constructor Create;
destructor Destroy; override;
procedure Clear;
function Count: Integer;
property Items[Index: Integer]: TMyClass read GetMyItem; default;
end;
implementation
{ TMyClass }
constructor TMyClass.Create(AOwner: TMyClasses);
begin
FOwner:= AOwner;
FOwner.FItems.Add(Self);
//Initialize some stuff...
end;
destructor TMyClass.Destroy;
begin
//Uninitialize some stuff...
inherited Destroy;
end;
{ TMyClasses }
constructor TMyClasses.Create;
begin
FItems:= TList.Create;
end;
destructor TMyClasses.Free;
begin
Clear;
FItems.Free;
inherited Destroy;
end;
procedure TMyClasses.Clear;
begin
while FItems.Count > 0 do begin
TMyClass(FItems[0]).Free;
FItems.Delete(0);
end;
end;
function TMyClasses.Count: Integer;
begin
Result:= FItems.Count;
end;
function TMyClasses.GetMyItem(Index: Integer): TMyClass;
begin
Result:= TMyClass(FItems[Index]);
end;
我认为有两种方法可以做到这一点,而这两种方法我都不信任。一种方法是在列表TMyClasses
对象FOwner.Lock;
(FOwner.Unlock;
一次,并且会破坏多线程的目的。第二种方法是在每个单独的对象中放置另一个关键部分,但是太多也很危险,对吧?我怎样才能保护列表和其中的每个对象清单在一起?