Search code examples
javamultithreadingrace-conditionsynchronized

No race condition: Two blocks with different locks but same shared data


I have two threads thread_1 and thread_2 calling different methods on the same object unsafeObj.

  • thread_1 calls unsafeObj.incrementVAR_v1() 10 times
  • thread_2 calls unsafeObj.incrementVAR_v2() 10 times

These two instance methods both have a synchronized-block with different locks (LOCK_1 and LOCK_2) accessing the same instance field VAR.

public void icrementVAR_v1() {
  synchronized(LOCK_1) {
    ++VAR;
    print("Thread 1: "  + VAR)
  }
}

public void incrementVAR_v2() {
  synchronized(LOCK_2) {
    ++VAR;
    print("Thread 2: " + VAR);
  }
}

👉 Given that these two synchronized-blocks use different locks I would have expected VAR being accessed concurrently and thus causing updates being lost (VAR less than 20). That's however not what I'm observing. Can someone please explain to me why that's not the case?

Example Output:

Thread 2: 2
Thread 1: 1
Thread 2: 3
Thread 1: 4
Thread 2: 5
Thread 1: 6
Thread 2: 7
Thread 1: 8
Thread 2: 9
Thread 1: 10
Thread 2: 11
Thread 1: 12
Thread 2: 13
Thread 1: 14
Thread 2: 15
Thread 1: 16
Thread 2: 17
Thread 1: 18
Thread 2: 19
Thread 1: 20

Solution

  • As I expected the concurrent access (due to having two different locks ) on the field VAR does result in a race condition, but in order to observe it one requires a big number of iteration (in my case 100'000 iterations in each thread). The lessons learned:

    • ☝ Race conditions are hard to reproduce
    • 👍 Use big number of iterations when trying to reproduce them