Thread interference
Last updated
Last updated
Interleaving of multiple threads that manipulate shared data using multiple steps leads to thread interference. You can’t assume that a single statement of Java code executes atomically as a single step by the processor. For example, a simple statement like incrementing a variable value might involve multiple steps like loading of the variable value from memory to registers (working space), incrementing the value, and reloading the new value in the memory. When multiple threads execute this seemingly atomic statement, they might interleave, resulting in incorrect variable values.
Let’s work with an example of a class Book, which defines an instance variable copies- Sold that can be manipulated using its methods newSale() or returnBook():
The threads OnlineBuy and OnlineReturn manipulate the value of class Book’s instance variable copiesSold in their run() using methods newSale() and returnBook():
Let’s see what happens when another class, say, ShoppingCart, instantiates a Book and passes it to the threads OnlineBuy and OnlineReturn:
In the preceding code method main() starts three threads—task1, task2, and task3. These threads manipulate and share the same Book instance, book. The threads task1 and task2 execute book.newSale(), and task3 executes book.returnBook(). As mentioned previously, ++copiesSold and --copiesSold aren’t atomic operations. Also, as a programmer you can’t determine or command the exact time when these threads will start with their execution (it depends on how they’re scheduled to exe- cute by the OS). Let’s assume that task2 starts with its execution and reads book .copiesSold. Before it can modify this shared value, it’s also read by threads task3 and task2, which are unaware that this value is being modified by another thread. All these threads modify the value of book.copiesSold and update it back in order. The last thread to update the value book.copiesSold overrides updates of the other two threads. Figure below shows one of the possible ways in which the threads task1, task2, and task3 can interleave.
So, how can you assure that when multiple threads update shared values it doesn’t lead to incorrect results? How can you communicate between threads? Let’s discuss this in the next section.