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

nav*_*ius 2 delphi methods static multithreading class

我是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;
Run Code Online (Sandbox Code Playgroud)

根据我的理解,SomeProcedure()将在内存和单个实例上静态,

我的问题

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

Dav*_*nan 7

不同的方法调用之间没有同步.如果方法,无论它们是什么类型的方法,访问共享数据,那么可能需要同步.

如果它们是类方法或实例方法,静态或动态等,它没有任何区别.重要的是是否有从多个线程访问的共享对象.

如果两个不同的线程访问了这个方法,FCounter怎么样?FCounter将从最后一个值或不同的线程开始按顺序计数,从零开始不同的值?

在您的代码中,FCounter是一个类变量.在所有线程之间共享一个变量的实例.类变量只是一个全局变量,仅此而已.

您的代码修改了该共享变量.正如所写,代码有数据竞争.您可以通过同步解决它.例如通过使用InterlockedIncrement而不是inc.

class procedure SomeProcedure;
begin  
  InterlockedIncrement(FCounter); 
end;
Run Code Online (Sandbox Code Playgroud)

对于更复杂的对象,您需要使用关键部分进行序列化.

  • 您的问题已经很清楚了,更新不会改变我的信息。你对分享有误解。正如我所说,重要的是线程之间的共享而不是类之间的共享。并行执行的单位是线程而不是类。 (2认同)

Joa*_*der 5

你的班级不是线程安全的.

使计数器线程安全的最简单方法是使用TInterlocked.Increment(FCounter)而不是Inc(FCounter).所有TInterlocked方法是原子操作执行,这同样适用于Windows API函数InterlockedIncrement(),它可以在这里也可以使用.

  • TInterlocked的解决方案首先发布在我的回答中.从另一个答案中复制解决方案然后得到合适的答案似乎是不公平的. (3认同)