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)
This is close but has an observable difference in at least one case:
If
witness != oldValue, thewitnessvalue 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 returnedwitnessdoesn'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
oldValuewithout having done the store. e.g. if multiple threads run this simultaneously with the sameoldValuewhenrefhas that value, they can all loadswitness = 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 updateref. You need to keep toboolreturn value fromcompareAndSetfor that.I don't think it is possible to do an exact emulation of
compareAndExchangewithout using locks ... which would largely defeat the purpose of using anAtomicReference.