Chemistry Reference and  Research
           
 
Periodic Table
- standard table
- large table
 
Chemical Elements
- by name
- by symbol
- by atomic number
 
Chemical Properties
 
Chemical Reactions
 
Organic Chemistry
 
Branches of Chemistry
Analytical chemistry
Biochemistry
Computational Chemistry
Electrochemistry
Environmental chemistry
Geochemistry
Inorganic chemistry
Materials science
Medicinal chemistry
Nuclear chemistry
Organic chemistry
Pharmacology
Physical chemistry
Polymer chemistry
Supramolecular Chemistry
Thermochemistry

Double-checked locking

Double-checked locking is a software design pattern originally known as "double-checked locking optimization". The pattern is usually 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 [1]):

// 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. Intuitively, the overhead of acquiring and releasing a lock every time this method is calling seems unnecessary: the main use of the lock appears to be ensuring that the initialization of the value will only be done once, but once the initialization has been completeted acquiring and releasing the locks would appear unnecessary. Many programmers have attempted to optimize this situation by:

  1. Checking that the value is initialised (without obtaining the lock). If the value is initialized, it can simply be returned.
  2. Obtaining the lock.
  3. Double-checking whether the value has already been initialized: if another thread acquired the lock first, it may have already done the initialization. If so, the initialized value can be returned.
  4. Otherwise, the value is initialized and returned.

Intuitively, this algorithm seems like an efficient solution to the problem. However, this technique has many subtle problems and should be usually be avoided. For example, considering the following sequence of events:

  1. Thread A notices that the value is not initialized, so it obtains the lock and begins to initialize the value.
  2. Due to the semantics of most programming languages, the compiler is allowed to update the shared variable to point to a partially-constructed object before A has finished performing the initialization.
  3. Thread B notices that the shared variable has been initialized (or so it appears), and returns the value — because it believes the value is already initialized, it does not need to acquire the lock. If the variable is used before A finishes initiallizing it, the program will likely crash.

One of the dangers of using double-checked locking is that it will often work: it is not easy to distinguish between a correct implementation of the technique and one that has subtle problems. Depending on the hardware platform, the compiler, the interleaving of threads by the scheduler and the nature of other concurrent system activity, failures resulting from an incorrect implementation of double-checking locking may only occur intermittently; reproducing the failures can be difficult.

Double-checked locking is an example of an anti-pattern.

Reference

01-04-2007 01:16:19
The contents of this article are licensed from Wikipedia.org under the GNU Free Documentation License. How to see transparent copy