Re: The D Programming Language
Andrei Alexandrescu (See Website For Email) wrote:
James Kanze wrote:
I get the feeling that Andrei is confusing atomic and
synchronized. Writes to pointers in Java are guaranteed to be
atomic; they're not "synchronized", neither in the usual sense,
nor in the Java language sense.
No, I just used synchronized in lieu of atomic (as the effect is the
same), as I clarified in a different post.
I thought it was just an accidental misuse of the
word---"confusing" was a poor choice of words on my part,
because I didn't think that there was any confusion in your
head.
On the other hand, given the parentheses above, I'm no longer
certain. Atomic and synchronized are definitly different
concepts, and have very different effects here. Synchronized
would guarantee defined behavior (but slow the execution up by a
factor of maybe 5). All Java guarantees (unless there's
something I've missed---always possible) is atomic.
Of course, this means that other threads can see pointers to
objects which aren't yet constructed. But that's generally true
in Java, even without threads; just call a virtual function from
a base class constructor.
This is defined behavior - I'd agree not the best choice, but defined.
It's not worth discussing it further.
Agreed.
Worse, other threads can see pointers
to objects which haven't yet been zero initialized (or
initialized at all). That is, of course, the undefined behavior
that Java supposedly doesn't have. (I'm rather surprised that
Andrei doesn't recognize this. IIRC, he's written on the
problems of double checked locking in the past, and this problem
is related.)
My understanding is that previous implementations of Java did have the
threading issues you mention, and that the work on the Java memory model
made it impossible for a thread to see an uninitialized object. So
according to my understanding, your representation of the situation is
perfectly accurate... as of four years ago.
Possibly. I've not kept up to date with Java, as I don't
normally use it. But the runtime cost would be extreme, if they
do guarantee it.
I've just checked the latest version of the specification, and
they do seem to have special wording to cover this:
# The write of the default value (zero, false or null) to
each variable synchronizes-with the first action in every
thread. Although it may seem a little strange to write a
default value to a variable before the object containing
the variable is allocated, conceptually every object is
created at the start of the program with its default
initialized values.
I'm not too sure how to interpret it, but the second sentence
seems to suggest that default initialization of an object
created after the thread has started must appear to have occured
before the start of the thread (or conceptually appears before
the start of the thread). I would be very curious to see how
this is actually implemented, because it seems like it would be
very, very expensive; it pratically means that every pointer
dereference must be surrounded by fences. Do implementations
really do this in practice? Or are there optimization
techniques which allow eliminating enough of the fences so that
the effect on performance is not important? (I'm not very up to
date with regards to optimization in a multi-threaded context.)
Or (what I suspect) do most implementations just ignore the
issue, hoping that there will be enough intervening accesses
involved in returning from the allocator and the delays
involving the garbage collector that no older values
will accidentally remained pipelined? (Or maybe there are
tricks that can be used with the garbage collector. I'll have
to think about this.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]