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

Dawid Kurzyniec dawidk@mathcs.emory.edu
Wed, 14 Jan 2004 23:56:37 -0500


> -----Original Message-----
> From: Ronald Bense [mailto:eqmel@comcast.net] 
> Sent: Wednesday, January 14, 2004 11:19 PM
> To: gregg.wonderly@pobox.com; 'Tim Peierls'
> Cc: 'Dawid Kurzyniec'; concurrency-interest@altair.cs.oswego.edu
> Subject: RE: [ Tim Peierls ] [concurrency-interest] Re: 
> AtomicInteger and AtomicLong should implement Number 
> 
> I still am not really convinced that they are "numeric" 
> values in the sense that Integers or other Numbers are. To 
> me, they are a container holding an int or long, which has 
> atomic change properties and from which I can obtain a 
> snapshot of the contained value via the get method.
> 
> However, having said that, I could potentially see where a 
> mutable Number object has value, perhaps in embedded systems, 
> where memory and performance have much tighter constraints. 
> In those situations, I could see where these features could 
> potentially be helpful. 

I often write low-level system code (I admit - not embedded systems),
but I never do any arithmetic on number wrappers. If you really have
tight performance/heap memory constraints, you don't write generic
algorithms which work on generic number wrappers in a type-neutral way,
but you rather settle with some degree of redundancy by providing
specialized versions working with primitive types. (java.util.Arrays
class is a good example). And usually you don't even have to, because
most of the time you know the types you work with. Some things are ints,
others are doubles, sometimes there are characters and bytes (but
usually within arrays), and you tend to have different algorithms for
all them. Greg claimed he had a valid use case for Numbers in embedded
systems, but he failed to prove it when challenged (and I attribute his
emotions to good intentions and strong beliefs, so no offense taken).

> So, perhaps they should have full numeric capabilities, along 
> with a stern warning in the javadoc that this is provided 
> only for special circumstances and should not be used for 
> hash keys or sorting due to the mutability of the underlying 
> value. (Too bad there's only the deprecated tag to cause warnings...) 

Well, I thought about that, but: 

First of all, people tend not to read javadoc if they believe they
understand the API. With autocompletion etc., I do it all the time.
(Although for equals() and hashCode(), I agree that it is a little
different, because you want to know how is equivalence defined)

But, more importantly: I doubt it is possible to document it in javadocs
in a way it does not sound, well, idiotic:

/** This class is intended to support efficient unsynchronized
concurrent atomic modifications
     of an int value. DON'T use the fact that this class is comparable
and overrides hashCode()
     unless the value is constant. (DOH!)*/
class AtomicInteger implements Comparable {
  /* returns a hashCode based on the value currently hold, to allow this
object serve as a hash key. 
   * But DON'T use it as a hash key unless the value is constant
(DOH!)*/
  public boolean hashCode() {...}

  /* compares two atomics. But DON'T rely on this method to sort or put
stuff in a tree map
   * unless both values are constant. (DOH! again)*/
  public int compareTo()
}

How can you avoid contradiction between the general purpose of the class
stated in the class doc and restrictions of the usage of hashCode()
etc., especially given the documentation of Object.hashCode() and
Comparable?...


While I was writing it, other thing stroke me: the value-based equals()
returning true does not even guarantee that the values EVER were the
same, given the inherent race condition between reading values of two
atomics and their possible concurrent modifications.

It is just to supplement my previously stated (and more significant)
objections regarding the comparable issue.

Regards,
Dawid