2023-05-03 11:06:20 +02:00
== Why is this an issue?
2021-04-28 16:49:39 +02:00
Double-checked locking can be used for lazy initialization of ``++volatile++`` fields, but only if field assignment is the last step in the ``++synchronized++`` block. Otherwise you run the risk of threads accessing a half-initialized object.
2021-04-28 18:08:03 +02:00
2023-05-03 11:06:20 +02:00
=== Noncompliant code example
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,java]
2021-04-28 16:49:39 +02:00
----
public class MyClass {
private volatile List<String> strings;
public List<String> getStrings() {
if (strings == null) { // check#1
synchronized(MyClass.class) {
if (strings == null) {
strings = new ArrayList<>(); // Noncompliant
strings.add("Hello"); //When threadA gets here, threadB can skip the synchronized block because check#1 is false
strings.add("World");
}
}
}
return strings;
}
}
----
2021-04-28 18:08:03 +02:00
2023-05-03 11:06:20 +02:00
=== Compliant solution
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,java]
2021-04-28 16:49:39 +02:00
----
public class MyClass {
private volatile List<String> strings;
public List<String> getStrings() {
if (strings == null) { // check#1
synchronized(MyClass.class) {
if (strings == null) {
2021-06-04 14:23:34 +02:00
List<String> tmpList = new ArrayList<>();
tmpList.add("Hello");
2021-04-28 16:49:39 +02:00
tmpList.add("World");
strings = tmpList;
}
}
}
return strings;
}
}
----
2021-04-28 18:08:03 +02:00
2023-05-03 11:06:20 +02:00
== Resources
2021-04-28 16:49:39 +02:00
* https://wiki.sei.cmu.edu/confluence/x/6zdGBQ[CERT, LCK10-J.] - Use a correct form of the double-checked locking idiom
2023-05-03 11:06:20 +02:00
=== Related rules
2021-04-28 16:49:39 +02:00
* S2168 - Double-checked locking should not be used
2021-04-28 18:08:03 +02:00
2021-06-02 20:44:38 +02:00
2021-06-03 09:05:38 +02:00
ifdef::env-github,rspecator-view[]
2021-09-20 15:38:42 +02:00
'''
== Implementation Specification
(visible only on this page)
2023-05-25 14:18:12 +02:00
=== Message
Fully initialize this new "xxx" before assigning it to the field.
2021-09-20 15:38:42 +02:00
2021-06-08 15:52:13 +02:00
'''
2021-06-02 20:44:38 +02:00
== Comments And Links
(visible only on this page)
2023-05-25 14:18:12 +02:00
=== on 15 Jun 2015, 18:07:41 Ann Campbell wrote:
\[~tamas.vajk] I've targeted this to C# because I think it might be relevant.
=== on 17 Aug 2015, 06:56:13 Tamas Vajk wrote:
\[~ann.campbell.2] This seems very specific (to Java), I wouldn't target C#. There might be minor differences in the Java and C# memory model when using ``++volatile++``, which I'm not aware of.
=== on 17 Aug 2015, 16:08:28 Ann Campbell wrote:
Thanks for the review [~tamas.vajk]. Un-targeted.
2021-06-03 09:05:38 +02:00
endif::env-github,rspecator-view[]