The origin of the double lock
Single-mode embodiment, the DCL has a (double lock) implementation. In Java programs, and sometimes you may need to postpone some of the high overhead of object initialization operation, and only when these objects start initialization.
Examples of non-coded delay object initialization thread safe below.
In UnsafeLazyInitialization class, a thread of execution of code A 1 is assumed at the same time, B 2 thread executes the code. At this point, A thread might see reference to the object instance initialization is not yet complete.
For UnsafeLazyInitialization class, we can implement lazy initialization thread-safe doing synchronized to getInstance () method.
Sample code is as follows.
Due to the getInstance () method to do the synchronization process, synchronized will lead to performance overhead. If the getInstance () method is frequently invoked multiple threads, it will lead to a decline in program execution performance.
Conversely, if the getInstance () method will not be invoked frequently by multiple threads, then the delay initialization program will provide satisfactory performance.
Later, he proposed a "smart" Tip: double-checked locking (Double-Checked Locking). I want to reduce synchronization overhead by double-checked locking.
The following example code delay is achieved using double-checked locking initialized.
Double-checked locking seems perfect, but this is a wrong optimization!
In the first thread to execute the code read instance is not null, an object reference instance has not been possible to complete the initialization.
Root of the problem
Double check foregoing fourth example of the locked code (instance = new Instance ();) creates an object. This line of code can be divided into three lines of pseudo-code below.
Between the upper 3 lines of pseudo code 2 and 3, it may be reordered (in some JIT compiler, this reordering occurs is true), then execution timing of reordering between 2 and 3 as follows:
Multi-threaded execution timing table
T1 A1: assignment of memory
T2 A3: set point memory instance
T3 B1: determining whether the instance is empty
T4 B2: Since instance is not null, thread B will access the object instance reference
T5 A2: initialize the object
T6 A4: access to the object instance references
After know the root of the problem happening, we can think of two ways to achieve lazy initialization thread-safe.
1) does not allow 2 and 3 reordering 2) allows the reordering 2 and 3, but does not allow other threads to "see" this reordering.
Both solutions described later, corresponding to the above two points.
A Solution
Based volatile solutions
Note: This solution requires version JDK5 or later (since start using the new JSR-133 specification memory model from JDK5, this specification enhances the semantics of volatile).
When an object is declared after a reference volatile, re-ordering between the rows 3 and 2, pseudo-code 3, in a multithreaded environment it will be prohibited.
Solution two
Class-based solutions for initialization
(Ie, before the Class is loaded, and the threads) JVM's class initialization phase, will perform initialization class.
During initialization execution class, JVM will go to get a lock. The lock can synchronize multiple threads to initialize the same class.
Based on this feature, you can achieve another thread-safe lazy initialization program (this program is called Initialization On Demand Holder idiom).
Field initialization delay reduces the cost of creating or initializing a class instance, but increases the cost of access is lazy initialization field.
Most of the time, better than normal initialization delay initialization. If you do need a delay to initialize the instance fields using thread-safe, use the description above based on lazy initialization of volatile solution; if you really need a delay to initialize static fields using thread-safe, use the description above class-based initialization scheme.
Little brother feel good essays give a point to focus on it, give it more gradually.
Finally, share an interview book "Java Core knowledge finishing .pdf", covering the JVM, locks, high concurrency, reflection, Spring principle, micro-services, Zookeeper, databases, data structures, and so on. Add to my personal fan base (Java technology stack architecture: 644 872 653) for a free way to receive.