Race Condition in Java

Race condition in Java may occur in a multi-threaded language like Java when two or more threads try to access a shared resource. If all the threads are just reading a shared object that poses no problem but modifying or writing a value may lead to incorrect results because of race condition.

In a multi-threaded environment, a thread after executing few steps may be preempted by another thread. That may leave the shared data in an inconsistent state.

For example take the simple task of incrementing a counter – counter++;
This simple task of incrementing a counter actually comprises of three steps

  1. Read the value of counter variable.
  2. Increment the value by 1.
  3. Store the value of counter variable.

If there are two threads sharing this variable then the following scenario may happen-

At the end you end up with the counter value as 1 rather then the correct value 2 because of the interleaving threads. That’s what race condition can do to a shared object in a multi-threaded environment.

Error scenarios because of race condition

Because of the race condition, executing thread may read a stale value of shared object which may result in any of the following scenario.

  1. If thread has to execute some logic based on the value of the variable. Because thread may end up reading a wrong value it may not act the way it was supposed to. This scenario is known as check-then-act race condition.
  2. A thread has to read the current value, modify it and store the new value. Again because of the race condition thread may end up reading and modifying a stale value. This scenario is known as read-modify-write race condition.

Example of race condition in Java

Here is a simple example where a shared integer variable is incremented and the value is displayed. Ten threads are created and each thread increments and then displays the value of the variable. Expected behavior is that each thread should get a unique value between 1-9.

Output

In one of the run the output came as above (note that the output may vary). As you can see Thread 5, 3 and 6 have got the same value 6, Thread 7 and 9 have also got the same value 8.

Avoiding race condition in Java

Now when you know what is race condition and seen an example too where interleaving threads read the same value of the shared object. That brings us to the question how to avoid race condition in Java.

It is clear that you need to restrict access to the critical section (code where shared resource is modified). In Java that’s what synchronized keyword does; synchronizes the access to the shared resource. Using synchronization ensures that the atomic operations are executed as a single operation without thread interference.

In the example showed above synchronizing the method call should avoid the race condition.

Output

As you can see now every thread gets a unique value.

That’s all for the topic Race Condition in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

One Comment

  1. Pingback: Volatile Keyword in Java - KnpCode

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.