Please always tell us where you read something, so we can assess the source for ourselves.Michael Farragher wrote:I've just read . . .
I saw that and immediately thought about its hashCode() and equals() methods insteadMichael Farragher wrote:. . . the thread safety of type Person) . . .
Sometimes the only way things ever got fixed is because people became uncomfortable.
So you think there is no risk of of access whilst the Set is incompletely initialised, and my problem won't occur?Tim Holloway wrote:. . . synchronizing . . . "this" . . .
Campbell Ritchie wrote:Please verify from the Java® Language Specification whether instantiation of the field (declaration and initialisation) completes before the constructor or not. If it is possible for thread1 to instantiate the object and thread2 to access it before the backing Set/Map is completely initialised, then it won't be completely thread‑safe. You are liable to suffer an exception from the add method.
Campbell Ritchie wrote:So you think there is no risk of of access whilst the Set is incompletely initialised, and my problem won't occur?
Campbell Ritchie wrote:
So you think there is no risk of of access whilst the Set is incompletely initialised, and my problem won't occur?Tim Holloway wrote:. . . synchronizing . . . "this" . . .
Sometimes the only way things ever got fixed is because people became uncomfortable.
Sometimes the only way things ever got fixed is because people became uncomfortable.
Michael Farragher wrote:So Stephan, if I go
final Object o = new MyObject();
not only will o always point at an instance of MyObject, but all the fields of this type (and their fields) will be initialised, and other threads will see this initialised state provided that it's accessed appropriately ?!?
Michael Farragher wrote:Which really takes me back to my first question.
If Thread A executes the mySet assignment ( which creates a HashMap) and other threads execute the synchronized methods, how do we know that the map won't be null and point to the correct object ?
Sometimes the only way things ever got fixed is because people became uncomfortable.
Stephan van Hulst wrote:Java's memory model is described in the JVMS, not the JLS.
Sometimes the only way things ever got fixed is because people became uncomfortable.
Tim Holloway wrote:final has nothing to do with threading
Sometimes the only way things ever got fixed is because people became uncomfortable.
Mike Simmons wrote:Oh no - I'm not talking about multi-threading in a constructor. Not intentionally, anyway. But the reality is that if you construct in one thread, and then pass the reference to other threads, those other threads may see your object as if it hasn't been fully initialized.
Sometimes the only way things ever got fixed is because people became uncomfortable.
Example 17.5-1. final Fields In The Java Memory Model wrote:
The program below illustrates how final fields compare to normal fields.
The class FinalFieldExample has a final int field x and a non-final int field y. One thread might execute the method writer and another might execute the method reader.
Because the writer method writes f after the object's constructor finishes, the reader method will be guaranteed to see the properly initialized value for f.x: it will read the value 3. However, f.y is not final; the reader method is therefore not guaranteed to see the value 4 for it.
Sometimes the only way things ever got fixed is because people became uncomfortable.
Tim Holloway wrote:I'm pretty sure that application code doesn't get the object reference until the object is - as the spec says - "fully constructed".
Thus you' cannot pass the references of a construction-in-progress to other threads.
Stephan van Hulst wrote:
This is exactly what may happen if you assign the result of an object creation expression to a shared variable.
Sometimes the only way things ever got fixed is because people became uncomfortable.
Tim Holloway wrote:You cannot pass an object to another thread before construction is complete.
The value of y will never be 0 unless someone post-construction explicitly sets it to y for any other code or thread than the constructor code (or constructor code chain) and the thread that the object was constructed under.
Tim Holloway wrote:
Stephan van Hulst wrote:
This is exactly what may happen if you assign the result of an object creation expression to a shared variable.
We're going in circles here. The result of an "object creation expression" is a fully-created object. The object reference being assigned does not exist in the general application code space until construction is complete, shared or not.
An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.
A variable that is declared final cannot be assigned to (unless it is definitely unassigned (§16 (Definite Assignment))), because when an access of such a final variable is used as an expression, the result is a value, not a variable, and so it cannot be used as the first operand of an assignment operator.
Stephan van Hulst wrote:
Tim Holloway wrote:You cannot pass an object to another thread before construction is complete.
You absolutely can.
Stephan van Hulst wrote:It's a bit unfortunate that the example in the JLS doesn't use a private field for y.
What kind of corn soldier are you? And don't say "kernel" - that's only for this tiny ad:
Free, earth friendly heat - from the CodeRanch trailboss
https://www.kickstarter.com/projects/paulwheaton/free-heat
|