0

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

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

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

我像这样打开 MyClock.Change( 5000, 5000 );

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

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

4

3 回答 3

3

首先:阅读 Eric Lippert 的博文:你称之为“线程安全”的东西是什么?它将改变您对线程安全的看法,以及您将来如何提出类似问题。

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

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

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

于 2012-05-11T18:48:50.980 回答
2

也许你可以Interlocked.Increment(ref Int32)用来做递增?这是一个原子操作。

于 2012-05-11T18:47:42.453 回答
1

像这样递增

tickerCounter++;

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

如果只有一个线程正在修改该值,并且有许多线程读取该值,那么tickerCounter++从没有线程会遭受部分读取的意义上说,这是线程安全的。当然仍然存在竞争条件,但即使你使用Interlocked,也会有竞争。

于 2012-05-11T18:48:47.610 回答