user1539577
user1539577

Reputation: 202

Benign data race condition with two threads

Is this a race condition?

class A {
   int x; 

   update() {
      x = 5; 
   }

   retrieve() {
      y = x; 
   }
}

If update() and retrieve() are called by two different threads without any locks being held, given that there is at least one write in two accesses of a shared variable, this can be classified as a race condition. But is this truly a problem during runtime?

Upvotes: 0

Views: 702

Answers (1)

John Dvorak
John Dvorak

Reputation: 27277

Without locks, three things can happen:

  1. y gets the new value of x (5).
  2. y gets the old value of x (most likely 0).
  3. if writes into int are not atomic, then y can get any other value.

In Java, reads to an int are atomic, so the third option cannot happen. No guarantee about the atomicity in other languages.

With locking, the first two options can happen as well.

There is an extra challenge depending on the memory model, though. In Java, if a write is not synchronized, it can be arbitrarily delayed up until the next synchronisation point (the end of a synchronized block or an access to a volatile field). Similarly, reads can be arbitrarily cached up from the previous synchronisation point (the start of a synchronized block or an access to a volatile field). This can easily result in problems arising from stale cache. The end effect is that the second option can happen even if the first one was supposed to.

In Java, always use volatile with fields that can be accessed from other threads, or you'll be facing hard-to-debug race conditions arising from memory access reordering. The same warning applies in other languages that use a memory model similar to the one in Java - you may need to tell the compiler to not do these optimisations.

Upvotes: 2

Related Questions