李浩穎
李浩穎

Reputation: 47

Java 8 impl on Compare And Exchange (Not Compare and Set!)

In java 17, AtomicReference has the compareAndExchange method which is like compareAndSet, but instead of returning a boolean, it returns the value right before the atomic action. I need that to implement a custom concurrent structure.

Due to limitations on the project, I have to use only Java 8 features. Some digging revealed VarHandle which has compareAndExchange. However, VarHandle requires Java 9.

Therefore, it seems that I have to implement the compareAndExchange myself. But how to do so efficiently with the existing methods? (And what about the compareAndExchangeWeak version?)

(I cannot rely on any third-party libraries, BTW)

Upvotes: 1

Views: 601

Answers (1)

Stephen C
Stephen C

Reputation: 718758

This is close but has an observable difference in at least one case:

V witness = ref.get();
if (ref.compareAndSet(oldValue, newValue)) {
    return oldValue;
} else {
    return witness;
}

If witness != oldValue, the witness value is not necessarily the correct value of the reference at the instant we do the compare-and-set.

However, it is not clear whether that value would be useful anyway ... so "close but not exactly right" may be sufficient. With a 100% correct compareAndExchange, the returned witness doesn't tell the caller what the state of the reference is now. Another thread could have changed the reference by the time that caller tries to use the returned value.

For example, this could return a value that matches oldValue without having done the store. e.g. if multiple threads run this simultaneously with the same oldValue when ref has that value, they can all loads witness = oldValue, but only one will succeed the CAS. So you can't safely use the return value to determine whether your CAS "won the race" to update ref. You need to keep to bool return value from compareAndSet for that.

I don't think it is possible to do an exact emulation of compareAndExchange without using locks ... which would largely defeat the purpose of using an AtomicReference.

Upvotes: 6

Related Questions