The class at the bottom is an implementation of fast, thread safe, "lock free", lazy initializer.
I say "lock free", although it isn't completely; It uses a lock until it is initialized, and then replaces the call to get the data with one that doesn't use the lock. (Similar to a double checked lock with a volatile member; and from performance tests I get v. similar results.)
My question is; is this a good/safe thing to do?
(After I had written this I noticed that the .net 4.0 has a LazyInit<T>
which performs the same operations and more, but in a very highly contrived example that I created my implementation was slightly faster :-) )
NB Class has been modified to include Value
member, and volatile on the _get
class ThreadSafeInitializer<TOutput>
where TOutput : class
{
readonly object _sync = new object();
TOutput _output;
private volatile Func<TOutput> _get;
public TOutput Value { get { return _get(); } }
public ThreadSafeInitializer(Func<TOutput> create)
{
_get = () =>
{
lock (_sync)
{
if (_output == null)
{
_output = create();
_get = () => _output; // replace the Get method, so no longer need to lock
}
return _output;
}
};
}
}