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

Larry Riedel larryr@saturn.sdsu.edu
13 Jan 2004 00:46:59 -0000

> > I would say it would, regardless of anything to do with atomic vs not
> > atomic, be an inauspicious decision to use an object as a key in a
> > hashtable during a period of time when its value as a key might change
> > during the normal/expected course of events in the application.
> I have said it before: It HAS to do with atomic, since they are provided
> SPECIFICALLY to support unsynchronized concurrent modifications.

When I invoke compareAndSet(), I expect it to be functionally
equivalent to if its implementation did indeed do Java language level
synchronization; I would use the java.util.concurrent.Atomic* version
because it is (presumably) implemented to do that orders of magnitude
more quickly than if it used Java language level synchronization
because it is a particular scenario which has [hardware] support.

>                                                                 If you
> don't have multiple threads sharing the mutable variable (that's what
> confinement is about, BTW), you didn't need the atomic class in the
> first place. If you have multiple threads sharing the variable, there
> is NO period of time when the value-based hashcode can be relied upon
> as constant unless you perform locking (synchronization) which again
> defeats the purpose of using atomic class.

I imagine something like the following:  I have an object whose state
is queried often, maybe from one thread, maybe from another, and on
average the state of the object changes relatively seldom and relatively
predictably (deterministically), or maybe it never changes unless
something unusual happens.  When a decision is made to change the state
of the object, that decision and the new state are based in part on
what the existing state is believed to be.  There is no single thread
dedicated to (or with an exclusive mandate for) changing the state.
When the state does change, it must change directly from one correct
state to another.

For this particular application it may be very unlikely or almost
inconceivable that between the time a thread queries the state of the
object and commands the object to change its state, some other thread
commands the object to change state, but it COULD happen, and the
atomicity of that pair (query+command) of operations needs to be ensured
to preserve the invariants.  If for this application the query+command
pair fits the "compareAndSet" paradigm of Atomic*, I would like to use
that, because it seems like a simple/easy way to get good performance.

Besides the frequent querying of the object state, there are various things
the application does which leverages the fact that the state of the object
seldom (if ever) changes, by assuming the state will be constant during a
sequence of operations, or maybe it is virtually guaranteed to take place
between state changes because the completion of the sequence of operations
is one of the logical criteria affecting the decision to change the state of
the object.  Or maybe for some things the application does not mind if the
state changes and, for example, it cannot find an object in a hashtable--
maybe it just reverts to an iterator or some other alternative approach, or
just gives up until next time.

I prefer not to have the language/API preclude me from making my own
decisions about when to use the Atomic* classes and when to use a
hashCode() value which in the general case is not guaranteed to be
constant.  I am not meaning to say there is no clean/simple/efficient
way (or BETTER way) than the above to get the same end result for the
particular application, maybe having a single official state value
snapshot, or a single update thread.  I just think using the Atomic* is
a simple, natural, reasonable way to do it, and I have not seen anything
to make me think it should not be a supported way to do it.