我与delphi XE2相对较新,我想了解一些事情,如果我喜欢这段代码
TSomeClass=class
strict private
class var
FCounter:integer;
public
class procedure SomeProcedure();static
end;
implementation
class procedure SomeProcedure()
begin
inc(FCounter);
end;
initialization
begin
FCounter:=0;
end;
finalization
begin
FCounter:=0;
end;
据我了解,SomeProcedure()将在内存上静态,单个实例
我的问题
答案 0 :(得分:7)
不同的方法调用之间没有同步。如果方法,无论它们是什么类型的方法,访问共享数据,那么可能需要同步。
如果方法是类方法或实例方法,静态或动态等,它没有任何区别。重要的是是否有从多个线程访问的共享对象。
如果两个不同的线程访问了这个方法,怎么样 FCounter? FCounter将从最后一个值开始按顺序计数 或者具有不同值的不同线程从零开始?
在您的代码中,FCounter
是一个类变量。在所有线程之间共享一个变量实例。类变量只是一个全局变量,仅此而已。
您的代码会修改该共享变量。正如所写,代码有数据竞争。您可以通过同步解决它。例如,使用InterlockedIncrement
而不是inc
。
class procedure SomeProcedure;
begin
InterlockedIncrement(FCounter);
end;
对于更复杂的对象,您需要使用关键部分进行序列化。
答案 1 :(得分:5)
您的课程不是线程安全的。
使计数器线程安全的最简单方法是使用TInterlocked.Increment(FCounter)而不是Inc(FCounter)。所有TInterlocked方法都作为原子操作执行,这同样适用于Windows API函数InterlockedIncrement(),它也可以在这里使用。