1

I have a small question about Java AtomicInteger. I know that I can realise thread-safe counters. But I couldn't find anything about complex calculations with AtomicInteger.

For example I have this calculation (i and j are object-vars, "this"):

public void test(int x) {
    i = i + ( j * 3 ) + x
}

Is it possible to make this method thread-safe only with AtomicInteger?

Is this valid?

public void test(int x) {
    do {
        int tempi = i.get();
        int tempj = j.get();
        int calc = tempi + ( tempj * 3 ) + x;
    } while (i.compareAndSet(tempi, calc));
}

I think not because a thread could change j while the calculation. To avoid this I have to control if j is changed while the calculation. But I don't find a "just compare" function in AtomicInteger.

Pseudocode:

public void test(int x) {
    do {
        int tempi = i.get();
        int tempj = j.get();
        int calc = tempi + ( tempj * 3 ) + x;
    } while (i.compareAndSet(tempi, calc) && j.compare(tempj) /* changed */);
}

Can anybody help me to clarification?

daedsidog
  • 1,732
  • 2
  • 17
  • 36
  • 2
    No. Neither are valid as you say. The first because `j` may have changed and the second because you write anyway, then check `j`; if this check fails then you've already written. The only way to do this correctly would be to have some sort of external lock. You could try and pack two `int` into an `AtomicLong`, that way allowing you to have a single value again. – Boris the Spider Dec 05 '18 at 17:44
  • Perfect answer, thank you! –  Dec 05 '18 at 17:45

1 Answers1

3

Since your calculations operate on multiple AtomicXXX objects (i, j) they are not thread-safe. AtomicXXX semantics are implemented with Compare-and-Swap (CAS) instructions that do not support more than one placeholder at a time. You need an external monitor lock to make it thread-safe.

Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111