...
Code Block | ||||
---|---|---|---|---|
| ||||
public final class Helper { private final int n; public Helper(int n) { this.n = n; } // Other fields and methods, all fields are final } final class Foo { private Helper helper = null; public Helper getHelper() { Helper h = helper; // Only unsynchronized read of helper if (h == null) { synchronized (this) { h = helper; // In synchronized block, so this is safe if (h == null) { h = new Helper(42); helper = h; } } } return h; } } |
Exceptions
LCK10-J-EX0: Use of the noncompliant form of the double-checked locking idiom is permitted for 32-bit primitive values (for example, int
or float
) [Pugh 2004], although this usage is discouraged. The noncompliant form establishes the necessary happens-before relationship between threads that see an initialized version of the primitive value. The second happens-before relationship (for the initialization of the fields of the referent) is of no practical value because unsynchronized reads and writes of primitive values up to 32-bits are guaranteed to be atomic. Consequently, the noncompliant form establishes the only needed happens-before relationship in this case. Note, however, that the noncompliant form fails for long
and double
because unsynchronized reads or writes of 64-bit primitives lack a guarantee of atomicity and consequently require a second happens-before relationship to guarantee that all threads see only fully assigned 64-bit values (see VNA05-J. Ensure atomicity when reading and writing 64-bit values for more information).
...
Using incorrect forms of the double-checked locking idiom can lead to synchronization problems and can expose partially initialized objects.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
LCK10-J | Low | Probable | Medium | P4 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
CodeSonar |
| JAVA.CONCURRENCY.LOCK.DCL | Double-Checked Locking (Java) | ||||||
Coverity | 7.5 | DOUBLE_CHECK_LOCK | Implemented | ||||||
Parasoft Jtest |
| CERT.LCK10.DCL | Avoid unsafe implementations of the "double-checked locking" pattern | ||||||
PVS-Studio |
| V5304, V6082 | |||||||
SonarQube |
| S2168 |
Related Guidelines
Bibliography
[API 2014] |
Item 48, "Synchronize Access to Shared Mutable Data" | |
Item 71, "Use Lazy Initialization Judiciously" | |
[JLS 2015] | |
[Manson 2004] | JSR 133 (Java Memory Model) FAQ |
[Manson 2006] |
[Manson 2008] | Data-Race-ful Lazy Initialization for Performance |
[Shipilёv 2014] |
...