I've read that immutable objects under the JSR-133 memory model do not require any extra synchronization to be thread safe; they are thread-safe as-is. However, what about the object reference that points to an immutable object, does it require any synchronization?
If in my code I write:
String s = new String("hello");
// and later down in the code write
s = new String("goodbye");
will all threads that have access to s always see the correct string (hello/goodbye)? Or could there be caching issues, where one thread still points to the old immutable object ("hello")?
Do I ever have to declare references to immutable objects as volatile?
This topic has been locked.
4 replies Latest Post - 2008-03-27T17:38:32Z by SystemAdmin
Pinned topic Can a reference to an immutable object become stale?
Answered question This question has been answered.
Unanswered question This question has not been answered yet.
Updated on 2008-03-27T17:38:32Z at 2008-03-27T17:38:32Z by SystemAdmin
Re: Can a reference to an immutable object become stale?2007-12-05T00:21:21Z in response to shjohnson6This issue has been really bugging me, so I've been digging around on the internet. I found an article on the IBM developerworks website that claims outright that no synchronization is needed when using immutable objects:
"The new JMM JSR-133 also seeks to provide a new guarantee of initialization safety -- that as long as an object is properly constructed (meaning that a reference to the object is not published before the constructor has completed), then all threads will see the values for its final fields that were set in its constructor, regardless of whether or not synchronization is used to pass the reference from one thread to another."
If I'm interpreting this correctly, since immutable objects use only final instance fields, neither volatile nor any other form of synchronization is required to make the code above thread-safe.
If anyone has any thoughts or words of advice, I'd appreciate hearing them. Thanks!
SystemAdmin 110000D4XK1240 PostsACCEPTED ANSWER
Re: Can a reference to an immutable object become stale?2007-12-17T05:40:15Z in response to shjohnson6An Object and reference to it are not bound to each other. Their lifetime in many cases are different. You can change a reference without changing the object and vice versa, even you can assign some value that is of inherited type that is not thread safe.
If the reference is local variable you don't need to take care for it's thread safety as long as the actual object is thread safe.
On the other hand if the reference is part of the state of another object (ClassB) that is not immutable than you have to make the access to it thread safe.
volatile offers only visibility and border of reordering (when one thread changes the ref. it is guaranteed that the change will become visible (and all the other changes up to that point) ASAP, and if thread reads volatile ref. it is guaranteed that if value changed, the thread will get the most up-to-date value) More about volatile
So, the first short answer on your question is: The question is not well formulated.
If i try to guess what actually your question is: you should synchronize the access to the ref. or make it volatile (depends on how do you use this filed.)
Re: Can a reference to an immutable object become stale?2008-03-27T14:13:04Z in response to SystemAdminThanks for the response.
I was intentionally vague in my first post because I'm not interested in all the ways that an object reference can be made visible to different threads. When it does occur, and the reference in question refers to an immutable object, does that reference ever need synchronization? Why? This is what my first post is asking.
Before discussing it further I should clarify my vocabulary.
First of all, the term synchronization includes the use of both volatile variables as
well as synchronized blocks. Therefore, if I need to make the reference a volatile one, "synchronization" was needed.
According to Brian Goetz book, "Java Concurrency In Practice":
An object instance is immutable if it meets the following criteria:
- Its state cannot be modified after construction
- All its fields are final
- It is properly constructed (that the "this" reference does not escape during construction)
(See the following article to read more about letting "this" escape during construction: http://www.ibm.com/developerworks/java/library/j-jtp0618.html)
An object is published when it is made available to code outside of its current scope - such as by storing an object reference where other code can find it (ie a public instance variable), returning the reference from a public method, or passing the reference to a method in another class.
With that vocabulary in mind, we can talk about what kinds of safety guarantees are available for immutable objects and references to immutable objects.
Goetz talks about this when dealing with initialization safety:
- Immutable objects can be safely accessed even when synchronization is not used to publish the object reference.
- Initialization safety allows properly constructed immutable objects to be safely shared across threads without synchronization, regardless of how they are published - even if published using a data race.
- With the exception of immutable objects, it is not safe to use an object that has been initialized by another thread ...
Therefore, it appears that no synchronization is needed when constructing an immutable object. No volatile reference is needed. No synchronized block around the reference is needed.
However, the reference may still need synchronization if it is modified after that. For instance:
Assume s is visible to different threads:
ImmutableObject x = new ImmutableObject();
.... later in the code
s = x;
The reference s is not involved in construction so its not guarded by the initialization safety guarantees. In this case, synchronization is needed.
Lastly, it's probably dangerous to rely on initialization safety at all in real code. If the criteria for immutable objects listed above are not met, it cannot be used. If the final fields change after construction (see http://stuffthathappens.com/blog/2007/10/13/you-can-change-final-fields/), then initialization safety cannot necessarily be relied upon either.
I think good programming etiquette requires the use of some kind of synchronization around the reference, although its nice to know initialization safety is there.
Any other questions or comments are greatly appreciated.
SystemAdmin 110000D4XK1240 PostsACCEPTED ANSWER
Re: Can a reference to an immutable object become stale?2008-03-27T17:38:32Z in response to shjohnson6That's where atomic references are useful.
In your first example, if s was an atomic reference, you would have threading-wise clear semantics of the assignation and usage of the immutable object it refers to.