In C#, the following code (from this page) can be used to lazily instantiate a singleton class in a thread safe way:
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
lock(this) {
if (helper == null)
helper = new Helper();
}
}
return helper;
}
}
What would be the equivalent thread safe Delphi code?
The article also mentions two problems with Double Checked Locking in Java:
So while the code of the C# and the Java version in the mentioned article look almost identical, only the C# version works as expected. Which leads to the additional question if these two problems also exist in a Delphi version of Double-Checked Locking?
In multi-threaded environments, initialization is usually not thread safe, so locking is required to protect the critical section. Since only the first access requires locking, double-checked locking is used to avoid locking overhead of subsequent accesses.
Double-checked locking is a common pattern for lazy initialization of a field accessed by multiple threads.
No matter how you rig it, double-checked locking still fails Unfortunately, DCL isn't guaranteed to work under the current Java Memory Model (JMM.)
Double-checked locking is a pattern meant for reducing the overhead of locking. First, the locking condition is checked without synchronization. And only if the condition is met, the thread will try to get a lock. Thus, the locking would be executed only if it was really necessary.
Use System.TMonitor to lock the object instance in a thread safe way.
function TFoo.GetHelper(): THelper;
begin
if not Assigned(FHelper) then
begin
System.MonitorEnter(Self);
try
if not Assigned(FHelper) then
FHelper := THelper.Create();
finally
System.MonitorExit(Self);
end;
end;
Result := FHelper;
end;
For further reference look at Lock my object..., please! from Allen Bauer. In fact, the rep. I gather from this should go to Allen.
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