问题
In a single-threaded application I use code like this:
Interface
function GetNextUID : integer;
Implementation
function GetNextUID : integer;
const
cUID : integer = 0;
begin
inc( cUID );
result := cUID;
end;
This could of course be implemented as a singleton object, etc. - I'm just giving the simplest possible example.
Q: How can I modify this function (or design a class) to achieve the same result safely from concurrent threads?
回答1:
You can use the Interlocked*
functions:
function GetNextUID : integer;
{$J+} // Writeble constants
const
cUID : integer = 0;
begin
Result := InterlockedIncrement(cUID);
end;
More modern Delphi versions have renamed these methods into Atomic*
(like AtomicDecrement
, AtomicIncrement
, etc), so the example code becomes this:
function GetNextUID : integer;
{$J+} // Writeble constants
const
cUID : integer = 0;
begin
Result := AtomicIncrement(cUID);
end;
回答2:
The easiest way would probably be to just call InterlockedIncrement to do the job.
回答3:
With modern Delphi compilers it is better to use Increment function of class TInterlocked from unit System.SyncObjs. Something like this:
type
TMyClass = class
class var
FIdCounter: int64;
var
FId: int64;
constructor Create;
end;
constructor TMyClass.Create;
begin
FId := TInterlocked.Increment(FIdCounter);
end;
This helps to keep the code platform-independent.
来源:https://stackoverflow.com/questions/4016919/thread-safe-way-to-increment-and-return-an-integer-in-delphi