Wiki Markup |
---|
AccordingThe Java⢠toProgramming ArnoldLanguage, etFourth al.Edition \[[JPL 06|AA. Java References#JPL 06]\], "Section 14.10.2. Final Fields and Security" states: |
... indeed you can use
final
fields to define immutable objects. There is a common misconception that shared access to immutable objects does not require any synchronization because the state of the object never changes. This is a misconception in general because it relies on the assumption that a thread will be guaranteed to see the initialized state of the immutable object, and that need not be the case. 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. For example, suppose one thread creates aString
object and stores a reference to it in astatic
field. A second thread then uses that reference to access the string. There is no guarantee, based on what we've discussed so far, that the values written by the first thread when constructing the string will be seen by the second thread when it accesses the string.
It is unreasonable to assume not always the case that classes that use immutable objects are themselves immutable.
...
Compliant Solution (volatile
)
Immutable members can also be safely published by declaring them volatile as described in CON00-J. Declare shared variables as volatile to ensure visibility and prevent reordering of accesses.
Code Block | ||
---|---|---|
| ||
class Foo { private volatile Helper helper; public synchronized Helper getHelper() { // ... return helper; } public synchronized void initialize(int num) { helper = new Helper(num); } } |
Risk Assessment
The assumption that classes containing immutable objects are immutable is misleading and can cause serious thread-safety issues.
...