It's thread-safe as it is.
The default value for Lazy<T>
's LazyThreadSafetyMode
is ExecutionAndPublication
.
From the MSDN page on the new Lazy<T>(Func<T>)
constructor:
An instance that is created with this constructor may be used concurrently from multiple threads.
The thread safety mode of a Lazy instance that is initialized with this constructor is LazyThreadSafetyMode.ExecutionAndPublication.
If you were to use another overload where you could pass a different LazyThreadSafetyMode
value it wouldn't be thread safe. But using the constructor as you are now, it is thread safe.
EDIT: Regarding your additional edited question, if those methods on your SingletonClass1
type are not thread safe: then no, func1
is not thread safe either.
From the Lazy<T>
MSDN Page:
Making the Lazy object thread safe does not protect the lazily initialized object. If multiple threads can access the lazily initialized object, you must make its properties and methods safe for multithreaded access.
You will need to make sure that those methods/interactions between those classes are thread safe. This might be as simple as wrapping the func1
body with a lock
statement, but I can't say for certain depending on how your 3 instances of SingletonClass1
interact with each other or how calling code may access them.