在Delphi中,TInterfacedObject的autofree属性是否是线程安全的?

3

TInterfacedObject._ReleaseTInterfacedObject._AddRef是线程安全的吗? 我可以看到FRefCount是线程安全的,但Destroy没有受到锁或其他保护。

function TInterfacedObject._Release: Integer;
begin
  Result := InterlockedDecrement(FRefCount);
  if Result = 0 then
    Destroy;
end;

不同的线程能够同时执行 Destroy 导致竞争条件吗?


1
整个重点在于你不要调用destroy,因为你是通过接口而不是对象来进行操作的。 - undefined
我知道我不能直接调用Destroy。如果一个线程检查Result为0并尝试释放,而另一个线程增加引用,这种情况可能发生吗? - undefined
2
如果结果达到零,那么再也没有任何东西可以有参考了。 - undefined
即使在多线程环境下? - undefined
1
是的,即使在多线程情况下也是如此。如果引用计数降为0,则意味着对该对象根本没有任何引用。如果一个线程尝试增加引用计数,那么一开始肯定存在对该对象的引用,因此在线程增加引用计数时,引用计数不应该降为0。除非你正在进行一些不寻常的操作,例如在不进行引用计数的情况下传递引用。 - undefined
1个回答

5
TInterfacedObject中实现引用计数方法是线程安全的,因为引用计数是原子地增加和减少的。
当对象实例的引用计数在_Release方法中达到零时,这意味着不再有其他强引用指向该对象,销毁对象将是线程安全的。
同样地,当你查看_AddRef方法时,如果你已经有一个对对象的强引用,从中获取另一个强引用也是线程安全的。
然而,这并不是整个故事,处理跨多个线程的引用计数实例时还需要考虑其他事项。
  • 引用赋值不是线程安全的 - 你不能在多个线程中以线程安全的方式拥有一个变量并对其进行写入,除非使用额外的访问保护机制,确保只有一个线程可以同时访问该引用,比如锁。

  • 从弱引用中获取强引用不是线程安全的 - 如果线程只有一个对某个引用计数实例的弱引用,那么你不能以线程安全的方式将该弱引用分配给一个强引用


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接