5

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...

peps
  • 75
  • 1
  • 1
  • 6
  • Your code doesn't actually make any sense; no such methods exist. – SLaks May 11 '14 at 21:17
  • 2
    What's `value`? The question appears to imply it's an `AtomicInteger` but that doesn't have `get(int)`, `decrementAndGet(int)`, or `incrementAndGet(int)` methods, only methods of the same name without any arguments. –  May 11 '14 at 21:18

3 Answers3

14

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.

Boris the Spider
  • 59,842
  • 6
  • 106
  • 166
  • Will there be any possibility that it passes the if statement which it shouldn't? Sorry for that my english is not good :) – peps May 11 '14 at 21:26
  • 4
    @peps The problem is not just the `if`: You have quite a few atomic operations without any synchronization around them; each of them will execute atomically but the sequence of them will not. Another thread might barge in and mess things up in between any of these atomic operations. At the time `value.get(i)` returns something, that return value will be up-to-date and correct. But an instant later, possibly before this thread can do anything else, it might already be out-of-date because another thread modified that integer. –  May 11 '14 at 21:32
  • I got what you said :) – peps May 11 '14 at 21:38
4

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.

Alexey Malev
  • 6,408
  • 4
  • 34
  • 52
3

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

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

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • The `Atomic*` methods are thread-safe, but OP's use of them is not. I think the latter was asked (despite the title), but even if not it would be negligent not to at least mention it. –  May 11 '14 at 21:23
  • What part does not compile? Note the edit; `value` is an `AtomicIntegerArray`, not a single `AtomicInteger`. –  May 11 '14 at 21:26