0

I'm using AtomicInteger to compare and set synchronization state. Here is it

private final AtomicInteger state = new AtomicInteger(1);

public void tryDo(){
    if(state.compareAndSet(1, 2)){
        //do some usefule
    }
}

The question is if the following scenario possible:

  1. state = 1
  2. Two or more threads trying to compareAndSet the state to 2
  3. All the threads at 2. fails and the state remains 1

Is it documented? Is it platform dependent? How about x86-64?

Some Name
  • 8,555
  • 5
  • 27
  • 77

2 Answers2

3

See the contract for compareAndSet(int expect,int update):

... False return indicates that the actual value was not equal to the expected value.

So, by implication, if only these threads are accessing the value and you have confirmed that it is currently at 1 then the ONLY way for all to fail is if it was NOT at 1. QED.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
  • How about the contract of `lock cmpxchg` on x86-64? __To simplify the interface to the processor’s bus, the destination operand receives a write cycle without regard to the result of the comparison. The destination operand is written back if the comparison fails__ It means we can read the written value for all threads, no? https://www.felixcloutier.com/x86/CMPXCHG.html – Some Name Apr 05 '18 at 13:45
  • @SomeName - Then either there is more to the Java implementation of `compareAndSet` than just a `CMPXCHG`. i.e. one that ensures the documented contract is implemented - otherwise this is a bug (albeit a small one). – OldCurmudgeon Apr 05 '18 at 13:50
2

threads can be broken by another cause... I not sure I've got your question properly...

I would say that it is not possible if there are no other causes,
just have a look on AtomicInteger impl:

    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

    public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
dzrkot
  • 543
  • 2
  • 4
  • 23