...
A
...
common
...
misconception
...
is
...
that
...
shared
...
references
...
to
...
...
objects
...
are
...
immediately
...
visible
...
across
...
multiple
...
threads
...
as
...
soon
...
as
...
they
...
are
...
updated.
...
For
...
example,
...
a
...
developer
...
can
...
mistakenly
...
believe
...
that
...
a
...
class
...
containing
...
fields
...
that
...
refer
...
only
...
to
...
immutable
...
objects
...
is
...
itself
...
immutable
...
and
...
consequently
...
...
Section
...
14.10.2,
...
"Final
...
Fields
...
and
...
Security,"
...
of
...
Java
...
Programming
...
Language
...
,
...
Fourth
...
Edition
...
[
...
...
...
]
...
states:
...
The problem is that,
...
while
...
the
...
shared
...
object
...
is
...
immutable,
...
the
...
reference
...
used
...
to
...
access
...
the
...
shared
...
object
...
is
...
itself
...
shared
...
and
...
often
...
mutable.
...
Consequently,
...
a
...
correctly
...
synchronized
...
program
...
must
...
synchronize
...
access
...
to
...
that
...
shared
...
reference,
...
but
...
often
...
programs
...
do
...
not
...
do
...
this,
...
because
...
programmers
...
do
...
not
...
recognize
...
the
...
need
...
to
...
do it.
References to both immutable and mutable objects must be made visible to all the threads. Immutable objects can be shared safely among multiple threads. However, references to mutable objects can be made visible before the objects are fully constructed. TSM03-J. Do not publish partially initialized objects describes object construction and visibility issues specific to mutable objects.
Noncompliant Code Example
This noncompliant code example consists of the immutable Helper
class:
Code Block | ||
---|---|---|
| ||
it. {quote} {mc} The String example might be good for the intro...if the long quote was not a good idea, perhaps a "For example, ..." line will help {mc} References to both immutable and mutable objects must be made visible to all the threads. Immutable objects can be shared safely among multiple threads. However, references to mutable objects can be made visible before the objects are fully constructed. Rule [TSM03-J. Do not publish partially initialized objects] describes object construction and visibility issues specific to mutable objects. h2. Noncompliant Code Example This noncompliant code example consists of the immutable {{Helper}} class: {code:bgColor=#FFCCCC} // Immutable Helper public final class Helper { private final int n; public Helper(int n) { this.n = n; } // ... } {code} |
and
...
a
...
mutable
...
Foo
...
class:
Code Block | ||||
---|---|---|---|---|
| =
| |||
} final class Foo { private Helper helper; public Helper getHelper() { return helper; } public void setHelper(int num) { helper = new Helper(num); } } {code} The {{ |
The getHelper()
...
method
...
publishes
...
the
...
mutable
...
helper
...
field.
...
Because
...
the
...
Helper
...
class
...
is
...
...
,
...
it
...
cannot
...
be
...
changed
...
after
...
it
...
is
...
initialized
...
.
Furthermore, because Helper
is immutable, it is always constructed properly before its reference is made visible, in compliance with TSM03-J.
...
...
...
...
...
...
...
.
...
Unfortunately,
...
a
...
separate
...
thread
...
could
...
observe
...
a
...
stale
...
reference
...
in
...
the
...
helper
...
field
...
of
...
the
...
Foo
...
class.
...
Compliant
...
Solution
...
(Synchronization)
...
This
...
compliant
...
solution
...
synchronizes
...
the
...
methods
...
of
...
the
...
Foo
...
class
...
to
...
ensure
...
that
...
no
...
thread
...
sees
...
a
...
stale
...
Helper
reference:
Code Block | ||
---|---|---|
| ||
}} reference. {code:bgColor=#CCCCFF} final class Foo { private Helper helper; public synchronized Helper getHelper() { return helper; } public synchronized void setHelper(int num) { helper = new Helper(num); } } {code} |
The
...
immutable
...
Helper
...
class
...
remains
...
unchanged.
...
Compliant
...
Solution
...
(volatile
)
References to immutable member objects can be made visible by declaring them volatile:
Code Block | ||
---|---|---|
| ||
{{Volatile}}) References to immutable member objects can be made visible by declaring them volatile. {code:bgColor=#CCCCFF} final class Foo { private volatile Helper helper; public Helper getHelper() { return helper; } public void setHelper(int num) { helper = new Helper(num); } } {code} |
The
...
immutable
...
Helper
...
class
...
remains
...
unchanged.
...
Compliant
...
Solution
...
(
...
java.util.concurrent
...
Utilities)
...
This
...
compliant
...
solution
...
wraps
...
the
...
mutable
...
reference
...
to
...
the
...
immutable
...
Helper
...
object
...
within
...
an
...
AtomicReference
...
wrapper
...
that
...
can
...
be
...
updated atomically:
Code Block | ||
---|---|---|
| ||
atomically. {code:bgColor=#CCCCFF} final class Foo { private final AtomicReference<Helper> helperRef = new AtomicReference<Helper>(); public Helper getHelper() { return helperRef.get(); } public void setHelper(int num) { helperRef.set(new Helper(num)); } } {code} |
The
...
immutable
...
Helper
...
class
...
remains unchanged.
Risk Assessment
The incorrect assumption that classes that contain only references to immutable objects are themselves immutable can cause serious thread-safety issues.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
VNA01-J | Low | Probable | Medium | P4 | L3 |
Automated Detection
Some static analysis tools are capable of detecting violations of this rule.
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
ThreadSafe |
| CCE_SL_INCONSISTENT | Implemented | ||||||
SonarQube |
| S2886 | Getters and setters should be synchronized in pairs |
Bibliography
Issue Tracking
Tasklist | ||||
---|---|---|---|---|
| ||||
unchanged. {mc} Sometimes I use the area before the risk assessment as a summary area for other CSs that can simply be mentioned to avoid redundancy, or CSs that are worth considering but have limitations which preclude us from recommending them. Basically general advice so that the implementer is not left wondering with a "what if I use ..." question. You deleted the line about making Helper immutable so where could such advice go? {mc} h2. Risk Assessment The incorrect assumption that classes that contain only references to immutable objects are themselves immutable can cause serious thread-safety issues. || Rule || Severity || Likelihood || Remediation Cost || Priority || Level || | VNA01-J | low | probable | medium | {color:green}{*}P4{*}{color} | {color:green}{*}L3{*}{color} | h2. Bibliography | \[[API 2006|AA. References#API 06]\] | | | \[[JPL 2006|AA. References#JPL 06]\] | 14.10.2, Final Fields and Security | h2. Issue Tracking {tasklist:Review List} ||Completed||Priority||Locked||CreatedDate||CompletedDate||Assignee||Name|| |F|M|F|1270826173609| |dmohindr|"Unfortunately, a separate thread -could- *can* observe a stale reference in the helper field of the Foo class."| |T|M|F|1270826698362|1271441478121|svoboda|"This compliant solution synchronizes the methods of *class* Foo -class- " (it sounds strange with class occuring after Foo)| {tasklist} ---- [!The CERT Oracle Secure Coding Standard for Java^button_arrow_left.png!|VNA00-J. Ensure visibility when accessing shared primitive variables] [!The CERT Oracle Secure Coding Standard for Java^button_arrow_up.png!|07. Visibility and Atomicity (VNA)] [!The CERT Oracle Secure Coding Standard for Java^button_arrow_right.png!|VNA02-J. Ensure that compound operations on shared variables are atomic] |
...