0

I want to write a Thread-safe method sum() but I'm not sure if I can use two AtomicIntegers to make it safe or do I have to use a synchronized block?

class A {

   private AtomicInteger a = new AtomicInteger();
   private AtomicInteger b = new AtomicInteger();

   public void sum(int c) {
      a.set(a.get() + b.get() + c);
   }
}
newlearner
  • 149
  • 1
  • 11
  • You ask if it's "thread-safe," but what does "thread-safe" mean to you? Is there any special relationship between the variables, `a`, `b`, and `c`? Could any of them be changed by the action of another thread? Would it be bad if the `a` and the `c` that you add together were the values from before the other thread performed its action, but the value of `b` was the value from _after_ the other thread did its thing? Thread-safety is mostly about preserving important relationships between different shared variables in a program, and only the author of the program can say what those are. – Solomon Slow Nov 25 '19 at 13:57

2 Answers2

2

The rules for evaluation order in Java mean that you’ll always follow a series of non-overlapping locks: A (get) -> B (get) -> A (set). So you won’t have any issues with blocking, because the locks won’t interfere with one another. Note that there is, however, a form of race condition: it is possible for thread 1 to read A, then read B. Before thread 1 sets A, thread 2 can read A and B. The final value will be one of the threads’ resulting sum, but the other will be lost.

MyStackRunnethOver
  • 4,872
  • 2
  • 28
  • 42
1

There are specific methods of AntomicInteger to take care of this. You don't need to break out of the AtomicInteger word and it's thread safety. Just checking the JavaDocs of AtomicInteger will show you methods like AtomicInteger.getAndAdd that you can use for this.

Nicktar
  • 5,548
  • 1
  • 28
  • 43
  • thanks, so it would be something like this right? a.getAndAdd( b.get() + c); – newlearner Nov 24 '19 at 18:44
  • 1
    That’s right, getAndAdd solves the thread issues in your example. But lookup getAndAdd so you see how it works. It returns the old value, while ‘a’ will contain the sum. – AndyMan Nov 24 '19 at 21:10