Lee said:
For example, there are no
contention problems for immutable objects (String, Integer, ...) because
they contain no mutable instance variables.
This is not strictly true, at least not according to my understanding of the
spec.
It's a bit off-topic for this thread, but consider:
Thread A constructs a new string:
-- (internally) creates and initialises a char array.
-- (internally) assigns a ref to that array to the field in the new String
object
Thread A assigns a reference to that String to a shared, volatile, location.
Thread B reads that location, since the location is volatile it guaranteed to
see the ref to the new object.
Thread B tries to use the String which (internally) reads the char array.
Potential problem, there is nothing to ensure that the char array, or its
contents, are yet visible to thread B; indeed there's no guarantee that the
String object "pointed to" by the reference is valid itself. That's because
neither thread has used a 'synchronized' block or method, and hence there is no
guarantee that their two views of memory are consistent.
As I understand it, synchronization is *always* necessary between threads, even
if all the shared objects are immutable once constructed. (Though it would be
OK if all the objects were created in a thread-safe way first)
-- chris