• Post Reply Bookmark Topic Watch Topic
  • New Topic

question about safe publish and threadsafe for immutable object

 
Robert Strong
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi, i'm new in multi-threading, i'm a little confused about safe publish and threadsafe of immutable object.

I know that immutable object is always threadsafe and can always be safely published thanks to initialization safety. does this mean that in the following code, the update() is threadsafe without synchronization?

public Cache {
private ImmutableObject holder;

public update(...) {
....
holder = new ImmutableObject(...);
}
}


any help is appreciated!
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No. While data within the ImmutableObject is safe (assuming it is, indeed, a properly-written immutable object), the reference "holder" is mutable, and not safe. This may or may not be a problem, depending what you do with it. But some threads may see an older, out-of-date value for the holder. And if you need to do conditional actions based on the state of the holder, e.g. update the holder if and only if it is null - that sort of thing can go badly wrong here unless you use synchronization, volatile, or other techniques.
 
Robert Strong
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike, thank you for your quick reply.

you said reference "holder" is mutable, other threads might see stale value of holder, but will initialization safety guaranty the most recent writes are visible to other threads?

 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's guaranteed that all data inside ImmutableObject (i.e., fields declared within that class) will be fully initialized, and observable as such from any thread that can reference a given ImmutableObject instance. But this guarantee does not, in any way, apply to the "holder" reference. Other threads may or may not see the most recent writes that have been made. But whatever they see, it will be a reference to a single, self-consistent object. It may be a single old self-consistent object, not the one you were expecting. But it won't be some mutant mishmash of two different objects.

Let's say ImmutableObject has two final fields, a String and an int, with an appropriate constructor and two getter methods. And let's say one thread executes something like


Sometime later, another thread executes


And then a short while later, yet another thread tries to read the value of "holder". They may well see an object with values of "B" and 2. Or they may, perhaps, see an object with values "A" and 1. That's an old, out-of-date object, but it's self-consistent. But they will never, ever see an object with values "A" and 2, or with values "B" and 1. Those are inconsistent - no object with such values was ever created.

However, if you drop the "final" from the declarations of both fields, then you no longer have a proper immutable object. (Well, unless you resort to other more complex techniques; I'm keeping this simple.) In this case you can observe an object with values of "A" and 2, or "B" and 1. Or "A" and 0, or null and 1, or null and 0. (The original default values may still be in place for some fields.) Weird stuff can happen if your object is not truly immutable.
 
Robert Strong
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike, thank you for your detailed, insightful descriptions.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!