The place where a variable is located does not imply any kind of thread safety. These are two completely different concepts.
What makes a variable thread safe or not is the way you manage access to it.
E.g., this would be thread safe, because the only way to manipulate FMyInt is through one of the three methods, which are all implemented in a thread-safe manner:
type
TMyClass = class
strict private
FMyInt : Integer;
public
procedure IncrementValue;
function QueryValue : Integer;
function SubtractValue( aWhat : Integer) : Integer;
end;
procedure TMyClass.IncrementValue;
begin
InterlockedIncrement( FMyInt);
end;
function TMyClass.QueryValue : Integer;
begin
result := InterlockedExchangeAdd( FMyInt, 0);
end;
function TMyClass.SubtractValue( aWhat : Integer) : Integer;
begin
result := InterlockedExchangeAdd( FMyInt, -aWhat);
end;
And so would this, but less efficient. Interlocked is not suitable for everyting so it really depends on the use case what method should be used.
type
TMyClass = class
strict private
FMyInt : Integer;
FLock : TCriticalSection;
public
constructor Create;
destructor Destroy; override;
procedure IncrementValue;
function QueryValue : Integer;
function SubtractValue( aWhat : Integer) : Integer;
end;
constructor TMyClass.Create;
begin
inherited;
FLock := TCriticalSection.Create;
end;
destructor TMyClass.Destroy;
begin
FreeAndNil( FLock);
inherited;
end;
procedure TMyClass.IncrementValue;
begin
FLock.Enter;
try
Inc(FMyInt);
finally
FLock.Leave;
end;
end;
function TMyClass.QueryValue : Integer;
begin
FLock.Enter;
try
result := FMyInt;
finally
FLock.Leave;
end;
end;
function TMyClass.SubtractValue( aWhat : Integer) : Integer;
begin
FLock.Enter;
try
Dec( FMyInt, aWhat);
result := FMyInt;
finally
FLock.Leave;
end;
end;
Note that the same works, if I put the values into a record
and have a bunch of functions and procedures doing the manipulation. The place where the variable(s) is/are stored, does not matter.
Do's & Dont's
Never mix different kind of locks. For example, mixing Interlocked-Functions with TCriticalSection, or mixing TCriticalSection with TMutex, or mix any kind of locks with completely unguarded access. Doing so would be a recipe for failure, because the different kinds of locks do not know each other.
Keep in mind that most lock mechanisms are only logical locks, which do not really prevent you from doing something insane with your data. It is therefore a good approach to encapsulate access to the data as much as possible to keep control.