質問

For example, if I run this code from multiple threads and each thread for many times, will there be potentially a data race?

   public boolean swap(int i, int j) {
    if (value.get(i) <= 0 || value.get(j) >= maxval) {
        return false;
    }
    value.decrementAndGet(i);
    value.incrementAndGet(j);
    return true;
}

BTW, is there any difference if I use decrementAndGet or getAndDecrement here?

value here is an AtomicIntegerArray. I need to do performance test among different synchronization method. So I swap elemtents in value and see if the output sum the same to what is expected

My task is to find a method that "should not be DRF," but "must still be deadlock-free", and is also much faster than ReentrantLock. So I'm troubling with finding a method that has data race...

役に立ちましたか?

解決

Yes, the incrementAndGet is thread safe.

incrementAndGet and getAndIncrement are the same as ++i vs i++. I.e.

int i = 0;
i++ // <- expression returns 0, i is now 1
++i // <- expression return 2, i is now 2

Ditto with decrement.

Your code, however, is not threadsafe as you call get twice across the || in the if. So the value could be changed between value.get(i) and value.get(j), whatever value is.

他のヒント

As written above, all methods of AtomicInteger is thread-safe.

will there be potentially a data race

Technically yes, there will be a data race, because

  • You call get twice while evaluating logical expression;
  • Saying "AtomicInteger is thread-safe" means that each thread calling for example value.decrementAndGet(i) (and all other CAS-based methods) will eventually complete this operation succefully. No other guarantees.

Using thread-safe class is not enough for preventing data races. Also I'd like to mention that data race is not always bad thing, sometimes it is acceptable actually.

Yes; all of the methods on the Atomic* classes are thread-safe.

The difference between decrementAndGet() and getAndDecrement() is which value it returns.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top