delphi - 类静态方法,多线程应用程序中的静态var

时间:2013-05-23 05:06:30

标签: multithreading delphi class methods static

我与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()将在内存上静态,单个实例

我的问题

  1. 如果TSomeClass被许多线程访问,TSomeClass是否可以线程安全?或者它会在线程之间重叠?
  2. 如果是,我是否需要每个线程的关键部分?或者这种方法的另一种方法......
  3. 如果两个不同的线程访问此方法,FCounter怎么样? FCounter将从最后一个值或不同的线程开始按顺序从零开始计算?

2 个答案:

答案 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(),它也可以在这里使用。