Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why DateTime.Now needs to be thread-safe?

I am Reading Joe's Albahari C# threading tutorial:

Author explains why DateTime.Now needs to be thread-safe:

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.

According to MS docs, .NOW is public static DateTime Now { get; }, i.e. read-only property. Why bother with thread-safety, if it is read-only ? Two concurrent calls should be able to get the current time without interfering with each other ?

Edit: A lot of people, pointing out that questions is not very clear. I did make an assumption that it should be safe, because: it is read only and because it is time(always changing).

like image 228
newprint Avatar asked Oct 01 '14 15:10

newprint


People also ask

Is it safe to read a datetime from multiple threads?

If you read from one thread, and write from another, the reading thread might get corrupted values. Reading from multiple threads while having no writing threads at the same time is safe. Essentially the two 32 bit halves of a DateTime might contain values of different age when used from multiple threads at the same time.

What is thread safety in C++?

In multithreaded environments, we need to write implementations in a thread-safe way. This means that different threads can access the same resources without exposing erroneous behavior or producing unpredictable results. This programming methodology is known as “thread-safety”.

Is factorial () method thread safe?

Hence, it's considered to be thread-safe and can be safely called by multiple threads at the same time. All threads can safely call the factorial () method and will get the expected result without interfering with each other and without altering the output that the method generates for other threads.

How to achieve thread safety in Java?

So, another common approach that we can use for achieving thread-safety is implementing synchronized methods. Simply put, only one thread can access a synchronized method at a time while blocking access to this method from other threads. Other threads will remain blocked until the first thread finishes or the method throws an exception.


1 Answers

Joseph is giving an example. It's not that Now needs to be thread-safe, all static methods need to be thread safe.

But, let's look at the all statics scenario. Statics need to be inherently thread-safe because if they have any state it is effectively global (and thus have a need to be thread-safe) and any caller to the method/property would be unable to make that data local and thus not need to worry about thread-safety. i.e. the caller would not be able to make it thread-safe reliably because no other code could possibly know how this code tried to make it thread safe and thus really can't be thread safe.

For example, let's say this fictitious DateTime.Now was implemented (poorly) like this:

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

...because ticks is long, it will not be atomic in 32-bit mode. Thus, the assignment to the shared ticks needs to be synchronized. Joseph is saying that you can't simply do this:

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

...because any other code is free to do this:

var now = DateTime.Now;

...and thus your lock does nothing to make it thread-safe.

It's impossible for a consumer of a static method to ensure thread-safety of the call to the static, thus the onus is on the writer of the static to perform all the necessary steps to make it thread-safe.

like image 141
Peter Ritchie Avatar answered Oct 09 '22 23:10

Peter Ritchie