c#2.0 int32线程安全吗?

时间:2012-05-11 18:43:50

标签: c# thread-safety int32

我想增加一个在计时器事件处理程序中递增的整数,并由主和其他工作线程读取,即一个编写器线程和多个读取器线程。它会线程安全吗?

我的应用程序中有一个每5秒运行一次的计时器

MyClock = new System.Threading.Timer(new TimerCallback(this.Ticker),null,Timeout.Infinite,Timeout.Infinite);

我打开了这样的话 MyClock.Change(5000,5000);

如果我在Ticker处理程序中增加一个整数,就像这样 tickerCounter ++;

然后,我可以从同一应用程序的主线程或工作线程执行只读访问吗? 它是线程安全的吗?读者是否有机会阅读部分价值?或导致线程异常?

3 个答案:

答案 0 :(得分:3)

首先:阅读Eric Lippert的博文:What is this thing you call "thread-safe"?这将改变您对线程安全的看法,以及您将来如何提出类似问题。

读取将是原子 - 您永远不会看到“一半”更新 - 但您不一定会看到最新值。 (这意味着下一个增量可能会看到要增加的“旧”(较低)值。)

此外,增量本身并不是安全的 - 如果有多个线程同时递增,它们都可以读取相同的值,然后在本地递增,然后写入新值 - 因此结果可能是一个增量为1,即使10个线程正在递增。

您应该考虑使用Interlocked.Increment来执行增量。如果您使变量变为volatile,我相信当您想要阅读它时,您应该直接阅读它。

答案 1 :(得分:2)

也许您可以使用Interlocked.Increment(ref Int32)进行递增?这是一个原子操作。

答案 2 :(得分:1)

像这样增加

tickerCounter++;

在多个线程中,没有锁定,不是线程安全的。您可以使用Interlocked类来执行无锁,线程安全递增。

如果只有一个线程正在修改该值,并且有许多线程在读取该值,那么tickerCounter++是线程安全的,因为任何线程都不会遭受部分读取。当然还有竞争条件,但即使你使用Interlocked,也会有竞争。