Lew said:
Eric Sosman wrote in this thread on 2/12:
Actually, it does. The particular argument is an extension of the observation
that += and ++ both represent a read followed by a write, with an increment or
addition in there somewhere. Those are inherently separate operations.
Those who whine (not me!) actually suggest changing that, by adding
new bytecodes for a combined & atomic e.g. "read+add+write"
On re-thought, even Eric's argument seems not too strong anymore:
First, z is read,
Then y is atomically increased by the previously read value.
Then x ...
...
While e.g. "n" is increased, some other thread could modify "a" and "z".
Obviously, that is irrelevant to the current thread, which no longer
cares for "z"'s value, and not yet cared for "a"'s old value.
...
Finally the resulting value of "b" would be added to the new value of "a".
No ambiguities involved.
Also tell them that there already is an atomic version of that operation,
'AtomicInteger#getAndIncrement()', et al., to be happy that synchronization is
built in to the language, and to quit whining.
So it's all just about whether "++","--","+=" and "-=" would be made
shorthands for what is already possible by the Atomic* classes.
The real reason boils down to that those atomic operations are still
slightly slower than the non-atomic ones, while the cases not caring
about atomicity by far outnumber the others. That's why I added
those "(not me!)"s.
Afterall, making "++" and "--" and the "op="s atomic just for volatile
variables wouldn't seem all that wrong to me. As there is no "Math.sqrt="
operator your other snippet seems quite irrelevant.
Since 'synchronized' or similar is needed to synchronize such multiple
operations, and 'synchronized' and similar are built into the platform, it
makes sense that those mechanisms should apply to all situations involving a
mix of reads and writes, rather than to draw some arbitrary and hard-to-manage
boundary between mixes that are atomic and those that are not.
The "arbitrary" boundary would be imposed by the (relative) frequency
of single-variable atomic get&calc&sets versus complex multivariable blocks
needing overall synchronization. The same way, as this boundary exists
already between uses for volatile,Atomic* and synchronized.
Really, though, whining about the absence of a feature that is already
provided by other means is just stupidity and childish petulance.
Development of a language is like dynamic compression: tasks that are
found to occur frequently enough are made simpler and shorter (see 1.5's
new for-syntax, autoboxing, static imports...).
There's enough room to differ on what deserves simplification, and what
doesn't, but principially negating the usefulness of making shorter syntax
for any already existing functionality is just as childish as being overly
greedy for syntactic sugar.