06: What is Wrong with this code? Multithreading & wait/notify

An excellent written test question to assess your Java multi-threading knowledge. Please practice it by doing it yourself.

Q. Review the code shown below and then answer the following questions.

Q1. What does the above code do?
Q2. What are the issues with the above code?
Q3. How will you go about fixing it?
Q4. How will you convert the polling based solution to event based solution?


A1. The above code tries to create 10,000 integers from 0 to 9,999, and then batches them into sizes of 10 or more.

  1. The main thread spawns 2 new threads “Producer” and “Consumer
  2. Both threads share the same “list
  3. The “Producer” add numbers from 0 to 9,999 to the list, and the “Consumer” remove those numbers for consumption (i.e. printing) in batches.

A2. The issues with the above code are

#1. java.util.ConcurrentModificationException is thrown.

Learn more: https://www.java-success.com/dealing-concurrent-modifications-java/

#2. After 30ms the isDone value will be set to “true”, hence the consume thread comes out of the while(!isDone) loop, and completes even before processing all the numbers in the list. The “Producer” being a user or non daemon thread continues to add all the numbers even the “Consumer” thread exit. Once the “Producer” thread is done, the JVM exits.

A3. Here is the code that fixes the 2 issues mentioned above. This code will print a desired output, but still will not be correct, which you will see later that it may hang without completing.

Output:
A4. The above solution is polling based. What happens if you change producer and consumer wait times to 0?
It will fail to work as intended. Let’s use the event based approached with inter thread communication. The wait-notify pattern is used in a broad set of cases where one thread needs to tell other threads that some event has occurred.

  • one or more threads sits waiting for a signal;
  • another thread comes along and notifies the waiting threads (i.e. “wakes it/them up” with the signal).

Event driven solution with wait/notify

The wait/notify needs to be within a lock. The block level lock is placed on the “list“. So, the “list” is synchronized, and wait/notify also invoked on the “list”.

output:

Above code works, but inefficient. Why?

As “CopyOnWriteArrayList” is an enhanced version of ArrayList in which all modifications (add, set, remove, etc) are implemented by making a fresh copy, which is inefficient when used in loops. So, let’s use iterator.remove() as the underlying “list” is already synchronized.

output:


800+ Java Interview Q&As Menu

Top