@Riven: exactly that thought, but as noted put/get field/static instead. I want to think that it was always illegal from the verifiers standpoint, but not a mandated illegal transform (but heck I might be misremembering).

WRT: volatile. Err, I don't think that volatile changes anything in this case.

Quote

And unfortunately, and very occasionally, necessary.

Why's that? private constructor, externally visible creation method which calls constructor, makes the reference and return the new instance...done. That seems to cover all bases.

My understanding with the new memory model is that single thread access to a volatile is strictly in order, but no guarantees between (under the old it gave you atomic operations). That was not my understanding of memory barriers. Also i only ever properly learnt the old memory model (some company wanted me java certified!)

But then again... its been a while since i did any of this stuff outside Java. And these days with java.util.concurrent.*, there is not much more I need.

I have no special talents. I am only passionately curious.--Albert Einstein

The constructor is insured to be completed before the value of 'x' changes.

Then I can point you to any number of references that volatile has an affect on this (stopping out-of-order instructions being visible to another thread), as does whether the fields of the constructed object are final or not. Strengthening the semantics of volatile and final would seem to be a major part of the new memory model.

@delt0r: yes indeed. I can't recall the last time I wrote synchronized nor volatile.

@nsigma: In the sense that (assuming I'm not wrong) that volatile is a memory barrier, then yeah it changes things...but what I'm attempting to say is that 'x' doesn't need to be volatile to insure correctness (again that x is only set after the constructor is complete).

but what I'm attempting to say is that 'x' doesn't need to be volatile to insure correctness (again that x is only set after the constructor is complete).

Not sure if we're really going around in circles saying almost the same thing here?!

What I mean is, as far as I understand it.

x may be assigned before the constructor is complete.

x doesn't need to be volatile to ensure correctness in a single thread. This is not the same as saying the value of x is not set before the constructor is completed - instructions may still be out of order but correct with regards to the creating thread.

Without the use of volatile another thread can see x in a half-initialized state (unless all x's fields are final). Therefore volatile ensures that the constructor is really complete prior to assignment.

Unless I'm incorrect: no to points 1 & 3. x may not be assigned to a field prior to completion of the constructor. The only issue about x being volatile (other than memory barrier) is that if another thread previously read x before the assignment and re-examines it after, then it's not insured to have the up-to-date value as it's not require to re-read on each access.

The section on initialization safety specifically talks only about final fields.

The section on volatile / double-checked locking specifically talks about how the semantics of volatile were expanded to non-volatile fields within the constructed object, and how assignment of fields within the constructor can be reordered with respect to the assignment of the object itself.

Here, without any synchronization or volatile going on, the 2nd thread might have an inconsistent view of the memory modified by the first thread. Although thread 1 sees dep's reference fully constructed, thread 2 might only have seen the assignment to the dep variable, and not the memory initialized by OtherObject's constructor.

So in that rare situation, thread 2 sees a partially constructed object.

Going back to the original, bad double-checked lock in Math.random(), the problem is that the first check against the randomNumberGenerator field is not synchronized. The calling thread could see a non-null reference written by another thread that just completed initRNG() and think it doesn't need to instantiate the RNG. Since there was no synchronization, though, the actual instance might be in an inconsistent state to the calling thread and all bets of correctness are off.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org