>
> ... as well as a weaker conditional atomic update operation
> weakCompareAndSet. The weak version may be more efficient
^^^^^^
> in the normal case, but differs in that any given invocation of
> weakCompareAndSet method may fail, even spuriously ..."
^^^
> public final boolean compareAndSet(long expect, long update) {
> return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
[quoted text clipped - 3 lines]
> return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
> }
> It seems to me that 'weakCompareAndSet' is identical
> with 'compareAndSet'.
In the current Sun implementation.
> What difference between them ?
The specification.
Tom Hawtin
Red Orchid - 22 Nov 2006 14:41 GMT
Thomas Hawtin <usenet@tackline.plus.com> wrote or quoted in
Message-ID: <45644853$0$8731$ed2619ec@ptn-nntp-reader02.plus.net>:
> > It seems to me that 'weakCompareAndSet' is identical
> > with 'compareAndSet'.
[quoted text clipped - 4 lines]
>
> The specification.
"AtomicXXX.addAndGet" is so, too ?
The specification says that "AtomicXXX" support thread-safe
programming on single variables.
But, it seems to me that the implementation is not safe in a
multithreaded environment in some senses. "addAndGet" or
"incrementAndGet" etc are not atomic methods, accordingly
the calling order of them is not preserved. Moreover it is
possible that they can never finish their tasks at the worst.
This code is a part of "AtomicLong" source.
<code>
public final long addAndGet(long delta) {
for (;;) {
long current = get(); // P1
long next = current + delta;
if (compareAndSet(current, next)) // P2
return next;
}
}
public final long get() {
return value; // volatile
}
<code>
For Thread 0, 1 , .. N.
Between P1 and P2 of Thread_I, it is practicable that
Thread_J calls 'get()' and then finishs his task earlier
than Thread_I. Moreover Thread_J can call 'get()'
repeatedly with high priority.
Is my thinking wrong ?
Thomas Hawtin - 22 Nov 2006 16:53 GMT
> But, it seems to me that the implementation is not safe in a
> multithreaded environment in some senses. "addAndGet" or
There are so many senses of thread-safe...
> "incrementAndGet" etc are not atomic methods, accordingly
> the calling order of them is not preserved. Moreover it is
Either one method or the other should happen-before the other.
> possible that they can never finish their tasks at the worst.
Only if the architecture you are running on is unfeasibly unfair. but
then the same is true of synchronization (unsurprisingly).
If addAndGet needs to go around the loop again, that can only mean
another thread has made progress. It's not a deadlock. Because the body
is so short, it is not an important factor for any realistically
contended locks (although I believe you can make microbenchmarks where
it is a problem - and possibly on _HUGE_ machines with complicated
memory architectures).
> public final long addAndGet(long delta) {
> for (;;) {
[quoted text clipped - 15 lines]
> Thread_J calls 'get()' and then finishs his task earlier
> than Thread_I.
Yup. But it's still atomic. It's as if one method did it's entire
execution before the other. It doesn't matter which. Other operations in
either thread are not atomic together with the atomic operation.
> Moreover Thread_J can call 'get()'
> repeatedly with high priority.
Do you mean set? You could do. But progress would always be made be some
thread. Calling get does not cause addAndGet to reiterate.
There are a pair of relevant wikipedia aritcles:
http://en.wikipedia.org/wiki/Lock-free_and_wait-free_algorithms
http://en.wikipedia.org/wiki/Non-blocking_synchronization
Tom Hawtin