c# - 为什么 DateTime.Now 需要线程安全?

标签 c# .net multithreading

我正在阅读 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 文档,.NOWpublic static DateTime Now { get; },即只读属性。 如果它是只读的,为什么还要考虑线程安全呢?两个并发的调用应该可以互不干扰的获取到当前时间吧?

编辑:很多人,指出问题不是很清楚。 我确实假设它应该是安全的,因为:它是只读的,因为它是时间(总是在变化)。

最佳答案

约瑟夫正在举一个例子。并不是说 Now 需要线程安全,所有静态方法都需要线程安全。

但是,让我们看看所有静态 场景。静态需要本质上是线程安全的,因为如果它们有任何状态,它实际上是全局(因此需要是线程安全的) 并且该方法/属性的任何调用者都无法使该数据成为本地数据,因此不需要需要担心线程安全。即调用者无法可靠地使其成为线程安全的,因为没有 其他代码可能知道这段代码如何尝试使其成为线程安全,因此实际上不能是线程安全的。

例如,假设这个虚构的 DateTime.Now 是这样(糟糕地)实现的:

private static long ticks;
public static DateTime Now
{
  get
  {
     ticks = UnsafeMethods.GetSystemTimeAsFileTime()
     return new DateTime(ticks); 
  }
}

...因为 tickslong,所以在 32 位模式下它不是原子的。因此,对共享 ticks 的分配需要同步。约瑟夫说你不能简单地这样做:

lock(somelock)
{
   var now = DateTime.Now;
}

...因为任何其他代码都可以免费执行此操作:

var now = DateTime.Now;

...因此您的什么都不做以使其成为线程安全的。

静态方法的使用者不可能确保调用静态方法的线程安全,因此静态方法的编写者有责任执行所有必要的步骤以使其线程安全。

关于c# - 为什么 DateTime.Now 需要线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26144436/

相关文章:

c# - 如何在多个浏览器上并行运行 Selenium webdriver C# 测试

java - 同步类(class)级别以上的调用

java - 线程池中实际创建线程

c# - Action<T> 与委托(delegate)事件

c# - Blazor Preview 9 Razor 布局中记录器的问题

c# - 不需要分配结构类型的 out 参数

c# - VB.NET 与 C# 的交叉兼容性

javascript - Visual Studio 2017 不显示 js 文件的折叠图标

c# - Process.Start() 无法打开 exe

c++ - 尝试创建线程的问题