我一直认为如果线程之间有共享变量且这个变量是原生类型,那么原子性应该可以解决问题。
但是根据下面代码的输出结果,在Delphi中并非如此。
线程t1简单地将计数器递增10M次。 同时,线程t2将计数器递减10M次。 因此,预期的计数器值在最后应该是0,但是我每次读取到的值都不同。
在Delphi中,没有锁定的情况下分享原生变量的正确方法是什么?
procedure TForm1.Button1Click(Sender: TObject);
var
t1, t2: TThread;
Counter: NativeInt;
begin
Counter := 0;
// first thread to increment shared counter
t1 := TThread.CreateAnonymousThread(
procedure ()
var
i: Integer;
begin
for i := 1 to 10000000 do
Inc(Counter);
end
);
// second thread to decrement shared counter
t2 := TThread.CreateAnonymousThread(
procedure ()
var
i: Integer;
begin
for i := 1 to 10000000 do
Dec(Counter);
end
);
t1.FreeOnTerminate := false;
t2.FreeOnTerminate := false;
// start threads
t1.Start;
t2.Start;
// wait for them to finish
t1.WaitFor;
t2.WaitFor;
t1.Free;
t2.Free;
// print the counter, expected counter is 0
Caption := IntToStr(Counter);
end;
TInterlocked
设计的初衷。 - Uwe Raabe