[concurrency-interest] Re: AtomicInteger and AtomicLong should implement Number

Larry Riedel larryr@saturn.sdsu.edu
7 Jan 2004 06:46:50 -0000

> AtomicInteger cannot be a Number because it would break the
> hashcode contract.

Is there something besides the contract which says that
two object values which would be equals() must have the
same hashCode()?  It seems like that could be satisfied
by returning "get()".

> And it would not have a symmetric equals method.  

Less symmetric than for Long and Integer, which are both Numbers
and for which neither equals() or compareTo() claim to work
when one Number is an Integer and the other is a Long?  I would
expect that at any given instant, for AtomicInteger objects
a and b, a.equals(b) would be equal to b.equals(a), using a
straightforward implementation of equals().  No?

> Things might have been different had there been pre-existing
> classes MutableInteger, MutableLong, etc, but there aren't.

In JDK 1.4, CharBuffer has a method asReadOnlyBuffer() which
returns another CharBuffer object, or maybe the same one, if
it was already ReadOnly.  In general a CharBuffer object may
or may not be mutable.  CharBuffer has hashCode(), equals(),
and compareTo(), and those things return meaningful values
in just those contexts where they should be expected to, and
they are documented as such. There is no "MutableCharBuffer",
"WritableCharBuffer", no "ReadOnlyCharBuffer"... there is
CharBuffer.  Maybe the CharBuffer is mutable, and maybe it
is not.  The JDK trusts me to make it work.  I like that.

I guess the value returned by get() of an AtomicInteger object
may not be the same the next time I call it, so if it has an
"intValue()" method from Number which just returns "get()",
I may end up with a Number reference which does not always
give the same value from intValue().  I think I can be
trusted to deal with that and make it work.

I got the impression that with JDK 1.5 there was going to be a
continued recognition that getting hamstrung by the compiler or
runtime system is not something which makes programmers more
productive, and it is nice to avoid an API design approach "you
should not want to do that, or at least you probably should not,
most of the time, and if you did it would probably be because
you are confused or ignorant, therefore you may not do it,
even though you asked to be able to do it and it would not
be particularly cumbersome or difficult to allow it".

> ... AtomicLong is not related to Long.

I guess maybe it would be like "it looks like a duck, and
quacks like a duck, but it was born with no legs, so it doesnt
walk like a duck, and so should not be treated as equivalent to,
or even similar to, a duck, even though the behavior of a duck
with no legs would be indistinguishable in practice".  It looks
to me like an AtomicLong object which was never modified after
a certain time T, and had a "longValue()" from Number which it
implemented using "get()", it would look, from the point of
view of a user of a Number, amazingly similar to a Long.  No?

No matter what happens, I feel confident saying whatever comes
out of JSR-166 will be better than anything I would have
come up with... but that does not mean it could not be better.