Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Threads "synchronized"

This article talks about Java's "synchronized" keyword.

  ...
  private int foo;
  public synchronized int getFoo() { return foo; } 
  public synchronized void setFoo(int f) { foo = f; }

If a caller wants to increment the foo property, the following code to do so is not thread-safe:

  ...
  setFoo(getFoo() + 1);

If two threads attempt to increment foo at the same time, the result might be that the value of foo gets increased by one or by two, depending on timing.

Now, my question:

Why doesn't "synchronized" on setFoo() prevent the above bolded line?

like image 810
Kevin Meredith Avatar asked Feb 27 '13 17:02

Kevin Meredith


1 Answers

This is an example of a check-then-act race condition.

A scenario might happen like the following:

Thread-1 getFoo() returns 0
Thread-2 getFoo() returns 0
Thread-2 setFoo(1)
Thread-1 setFoo(1)

This would mean that two threads have attempted to increment foo but it has the effect of only being incremented once.

As other answers have identified, synchronizing the incrementation with a synchronized block locking on the same object as getFoo() and setFoo() will prevent this race condition because threads won't be able to interleave like above.

like image 180
Samuel Avatar answered Oct 30 '22 04:10

Samuel