What is wrong with this Java code? Heap Vs Stack, Thread safety & Synchronized

This post covers must know Java Multithreading basics – Heap Vs Stack, Thread-safety & Synchronization. When you have a multithreaded Java application, you need to code in a thread-safe manner. Java interviewers may ask you to detect thread-safety issues as discussed in here.

1.What is wrong with the following code?

java thread-safety code

A very simple code that should print numbers from 7 to 21. But does it?

2. Above code is NOT Thread-safe

If you run it multiple times, you will see that some numbers get repeated as shown below. You get five”15″s and three “12”s. The result will be unpredictable and you will get different results each time you run it.

3. What is happening under the covers in terms of Heap Vs Stack memory & thread-safety

As shown below in the diagaram, the local variable “fixed”, and the reference “counter” to the instance of the class “Counter” are stored in the stack. The instance of “Counter”, i,e. the object itself is stored in the heap. So, it will be shared by all the threads. The “++count” operation is not atomic and performs 3 operations under the covers:

Step 1: get value of count from heap
Step 2: add 1 to count (i.e. count = count + 1)
Step 3: write the new value back to the heap memory

So, it is possible that 5 threads read the same value of say “count = 8” and increment them all to “9”, and then when added with the fixed value of 6, resulting in five “15”s. Each time you run, you get different results. The above code is unpredictable.

Java Stack Vs Heap memory & thread-safety

4. How to fix the concurrency issue?

The above thread safety issue can be fixed two ways by controlling the access to the shared object “counter”.

Solution 1: Synchronized i.e. a lock on the performCount() method

This will put a lock on “counter” object so that when one thread is performing the other threads have to wait for the lock.

Output:

Why is locking of a method for thread safety is called “synchronized” and not “locked”?

When a method or block of code is locked with the reserved “synchronized” key word in Java, the memory (i.e. heap) where the shared data is kept is synchronized. This means,

When a synchronized block or method is entered after the lock has been acquired by a thread, it first reads (i.e. synchronizes) any changes to the locked object from the main heap memory to ensure that the thread that has the lock has the current info before start executing.

After the synchronized block has completed and the thread is ready to relinquish the lock, all the changes that were made to the object that was locked is written or flushed back (i.e. synchronized) to the main heap memory so that the other threads that acquire the lock next has the current info.

[ Further Reading: 7 Things you must know about Java locks and synchronized key word ]

Solution 2: AtomicInteger so that the increment operation is atomic

The “incrementAndGet()” on AtomicInteger happens atomically so that two or more threads cannot read the same value and increment them to the same result.

Output:

What does atomicity mean?

Learn more about atomicty:

1) 10+ Atomicity, Visibility, and Ordering interview Q&As in Java multi-threading

2) 9 Java Transaction Management Interview Q&As

More “What is wrong with this code?


Prepare to fast-track & go places

Answers are detailed to be useful beyond job interviews. A few Q&As each day will make a huge difference in 3 to 24 months depending on your experience.
Top