我正在阅读 Joe 的 Albahari C# threading tutorial :
作者解释了为什么 DateTime.Now
需要线程安全:
Wrapping access to an object around a custom lock works only if all concurrent threads are aware of — and use — the lock. This may not be the case if the object is widely scoped. The worst case is with static members in a public type. For instance, imagine if the static property on the DateTime struct, DateTime.Now, was not thread-safe, and that two concurrent calls could result in garbled output or an exception. The only way to remedy this with external locking might be to lock the type itself — lock(typeof(DateTime)) — before calling DateTime.Now. This would work only if all programmers agreed to do this (which is unlikely). Furthermore, locking a type creates problems of its own.
For this reason, static members on the DateTime struct have been carefully programmed to be thread-safe.
根据 MS 文档,.NOW
是 public static DateTime Now { get; }
,即只读属性。
如果它是只读的,为什么还要考虑线程安全呢?两个并发的调用应该可以互不干扰的获取到当前时间吧?
编辑:很多人,指出问题不是很清楚。 我确实假设它应该是安全的,因为:它是只读的,因为它是时间(总是在变化)。
最佳答案
约瑟夫正在举一个例子。并不是说 Now
需要线程安全,所有静态方法都需要线程安全。
但是,让我们看看所有静态 场景。静态需要本质上是线程安全的,因为如果它们有任何状态,它实际上是全局(因此需要是线程安全的) 并且该方法/属性的任何调用者都无法使该数据成为本地数据,因此不需要需要担心线程安全。即调用者无法可靠地使其成为线程安全的,因为没有 其他代码可能知道这段代码如何尝试使其成为线程安全,因此实际上不能是线程安全的。
例如,假设这个虚构的 DateTime.Now
是这样(糟糕地)实现的:
private static long ticks;
public static DateTime Now
{
get
{
ticks = UnsafeMethods.GetSystemTimeAsFileTime()
return new DateTime(ticks);
}
}
...因为 ticks
是 long
,所以在 32 位模式下它不是原子的。因此,对共享 ticks
的分配需要同步。约瑟夫说你不能简单地这样做:
lock(somelock)
{
var now = DateTime.Now;
}
...因为任何其他代码都可以免费执行此操作:
var now = DateTime.Now;
...因此您的锁
什么都不做以使其成为线程安全的。
静态方法的使用者不可能确保调用静态方法的线程安全,因此静态方法的编写者有责任执行所有必要的步骤以使其线程安全。
关于c# - 为什么 DateTime.Now 需要线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26144436/