Double checked locking pattern
Double-checked locking is a software design pattern originally known as "double-checked locking optimization". The pattern can be unsafe on modern computer hardware and/or optimising compilers.
It is typically used to reduce locking overhead when implementing "lazy initialisation" in a multi-threaded environment. Lazy initialisation avoids initialising a value until the first time it is accessed. E.g., in Java (as given by Bacon et. al):
// Single threaded version
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null)
helper = new Helper();
return helper;
}
// other functions and members...
}
However when using threads a lock must be obtained, in case two threads attempt to initialise the value simultaneously. Double-checked locking attempts to avoid obtaining the lock after the value has been initialised, by a) checking that the value is initialised before obtaining the lock: if so, just return the value. b) if not initialised, obtain the lock and double-check whether the value is initialised (in case another thread has initialised it while the current thread was waiting for the lock). c) initialise the value and return it.
This can fail on modern computer hardware and with certain optimising compilers, where the statements are not guaranteed to be executed in the exact order in which they were stated. The failing behaviour is that a) a first thread obtains the lock and starts to initialise the value b) due to reordering, it first assigns the value to an incomplete object, intending to finish the initialisation before releasing the lock c) however a second thread enters the function and takes the incomplete object, which under double-checked locking it can do without obtaining the lock.
Reference
Referenced By
Design pattern (computer science) | Design pattern (computing) | Software design pattern | Software desisgn pattern | Software pattern
|