>>>> Count appears to be thread-safe (except for the initial assignment,
>>>> which is quite common).
[quoted text clipped - 4 lines]
>
> http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.12.5
Yes, you are safe with the initial value. You are even safe (from 1.5)
if count were declared final.
> "For type int, the default value is zero, that is, 0."
The initialised value is 0, yes. However, there is still the question of
the assignment in this code. *Theoretically* increments could happen
before this assignment. The assignment would then trash the incremented
value.
> (2) in the initialization for the member
>
> So I can't see where there could be any uninitialized object leaking out
> even if the initial value was something other than 0.
Then you are failing to fully grasp the nature of threading (in the
presence of optimisations).
> Now, theoretically, I could invent various perverse cases using
> initializer blocks that would expose an incomplete object. Alternatively
> there is the case that seems easier to fall into where a super class
> registers an object before the subclass is finished initializing it, but
> I didn't see any such problems in the OPs code.
Not all of the original posters code was threaded. It is a public class.
But most importantly, that's all irrelevant. The Java memory model does
not guarantee anything like sequentially consistency. This isn't just
important on multi-threaded hardware, but on JVMs that optimise code
(i.e. pretty much any worthwhile production JVM).
>>> Does the initial assignment matter? How does one guard itself against
>>> such problems?
>
> Never place an object in ANY data structure which might be accessible
> to another thread anywhere until after ALL constructors have completed.
Good idea.
> An assignment of the result of a new does not violate this rule of thumb.
Not really true. You want a "happens-before" edge between construction
and use. Normally this just means proper synchronisation. Use of final
field semantics is another approach.
>> Usually it is assumed that objects will be passed to other threads in
>> a thread-safe manner.
[quoted text clipped - 3 lines]
>
> Really? Not in the OPs case; please explain.
Not in the (partial) code posted. But the class is public, so anything
could go on, even in code not yet written.
As I say, the usual unstated (and probably unknown by the author)
assumption is that the object is distributed to other threads in a
thread-safe manner. An obscure, nasty corner case is that if an object
with a finaliser is dropped immediately after construction (technically
after the Object constructor returns to the next subclass constructor),
then it is not transferred thread-safely to the finaliser thread it runs on.
Tom Hawtin

Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/
Chris Uppal - 17 Dec 2005 12:08 GMT
> An obscure, nasty corner case is that if an object
> with a finaliser is dropped immediately after construction (technically
> after the Object constructor returns to the next subclass constructor),
> then it is not transferred thread-safely to the finaliser thread it runs
> on.
Do you care to expand on that ?
I'm finding it hard to see how there's a problem. In the first case I can't
think of any way that a reference to an object /can/ be dropped before all its
constructors have completed (either by a normal return or a thrown exception).
In the second, I don't see how that, if it happened, would affect how the
object is put on the finalisation queue. And if enqueuing doesn't involve (the
equivalent of) crossing a synchronisation barrier, then it's more than a "nasty
corner case", it's a sodding great hole in the implementation !
-- chris