rspec/rules/S3064/java/rule.adoc

67 lines
1.5 KiB
Plaintext
Raw Normal View History

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 16:49:39 +02:00
== Noncompliant Code Example
----
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 16:49:39 +02:00
== Compliant Solution
----
public class MyClass {
private volatile List<String> strings;
public List<String> getStrings() {
if (strings == null) { // check#1
synchronized(MyClass.class) {
if (strings == null) {
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 16:49:39 +02:00
== See
* https://wiki.sei.cmu.edu/confluence/x/6zdGBQ[CERT, LCK10-J.] - Use a correct form of the double-checked locking idiom
=== See Also
* S2168 - Double-checked locking should not be used
ifdef::env-github,rspecator-view[]
'''
== Comments And Links
(visible only on this page)
include::comments-and-links.adoc[]
endif::env-github,rspecator-view[]