(After asking this related question , I still have a question.)
The whole idea(AFAIK) with Lazy<T> , is to create the object only when we need it.
Why ? becuase it's expensive to create.
The last thing I would want is that the Expensive object will be created >1 times.
I don't care if many threads will eventually yields the same reference. I just don't want them to create more than one instance.
so Lazyinitializer handle this by syncLock:
LazyInitializer.EnsureInitialized (ref _expensive, ref useless, ref _sync, () => new Expensive());
But how does Lazy<T> can handle it ?
I've searched in msdn and couldnt find any syncLock overload ...
What am I missing ?
Are you asking how Lazy works internally? Lazy does guarantee that only one will ever be created, as per the MSDN documentation:
By default, Lazy objects are thread-safe. That is, if the constructor does not specify the kind of thread safety, the Lazy objects it creates are thread-safe. In multi-threaded scenarios, the first thread to access the Value property of a thread-safe Lazy object initializes it for all subsequent accesses on all threads, and all threads share the same data. Therefore, it does not matter which thread initializes the object, and race conditions are benign.
If you are in fact asking how it works internally, it seems to be using a lock of some sort:
object obj = Volatile.Read<object>(ref this.m_threadSafeObj);
bool flag = false;
try
{
if (obj != Lazy<T>.ALREADY_INVOKED_SENTINEL)
{
Monitor.Enter(obj, ref flag);
}
if (this.m_boxed == null)
{
boxed = this.CreateValue();
this.m_boxed = boxed;
Volatile.Write<object>(ref this.m_threadSafeObj, Lazy<T>.ALREADY_INVOKED_SENTINEL);
}
else
{
boxed = (this.m_boxed as Lazy<T>.Boxed);
if (boxed == null)
{
Lazy<T>.LazyInternalExceptionHolder lazyInternalExceptionHolder = this.m_boxed as Lazy<T>.LazyInternalExceptionHolder;
lazyInternalExceptionHolder.m_edi.Throw();
}
}
}
finally
{
if (flag)
{
Monitor.Exit(obj);
}
}
Notice the Monitor.Enter and Monitor.Exit calls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With