Saturday, September 24, 2016

How to solve Producer Consumer problem in Java using wait and notify method

Producer Consumer problem can be easily solved by using just wait and notify method using inter-thread communication where one thread is used to produce and another thread is used to consume. Here the wait and notify method will be used for inter-thread communication to notify other party (Producer by Consumer thread and vice-versa).

To solve this problem, I have used the ArrayList as shared object, where producer thread puts the object (Just Integer in this case) and consumer thread consumes the object (integer). Interestingly, I have used the same list object as monitor lock, thus removing the additional overhead to create shared monitor lock.


Here is the code example:


import java.util.ArrayList;

public class ProducerConsumer {

 public static void main (String[] args) {
  ArrayList<Integer> list = new ArrayList<Integer>();
  Thread t1 = new Thread(new Producer(list));
  Thread t2 = new Thread(new Consumer(list));
  t1.start();
  t2.start();
  
 }
}

class Producer implements Runnable {
 
 private ArrayList<Integer> list;
 Producer(ArrayList<Integer> list) {
  this.list = list;
 }

 @Override
 public void run() {
  int count = 1;
  while(count <= 3) {
   synchronized(list) {
    list.add(count);
    System.out.println("Produced ::"+ count);
    count++;
    try {
     list.notify();
     list.wait();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  }
  
 }
}


class Consumer implements Runnable {
 
 private ArrayList<Integer> list;
 Consumer(ArrayList<Integer> list) {
  this.list = list;
 }
 
 @Override
 public void run() {
  int count = 1;
  while(count <= 3) {
   synchronized(list) {
    while(list.size() == 0){
     try {
      list.notify();
      list.wait();
     } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
    }
    Integer value = list.remove(0);
    System.out.println("Consumed ::"+ value);
    count++;
    try {
     list.notify();
     list.wait();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  }
 }
}

Output:

Produced ::1
Consumed ::1
Produced ::2
Consumed ::2
Produced ::3
Consumed ::3

Explanations:

In the above code example, we are starting two threads (one Producer and one Consumer). To avoid the consumer start executing and consuming first, I have put code to check if producer has already produced or not (i.e. if there is anything on list or not). This is to address race-condition between producer and consumer threads.
Here, the producer thread is putting 3 objects (Integer in the example) in the list. Please note that the call by Producer thread and Consumer thread to put objects and retrieve objects is synchronized on the same lock (array list object in this example). This way, we guarantee that either the code of producer or code of consumer is executing inside cpu and not both at the same time. We have produced three objects and consumed three synchronously i.e producer put one, consumer consumed then again producer produced another  and ...
So, when producer produced an object, it calls notify to make sure that if the consumer threads is in waiting state, it goes back to runnable state and ready to consume and the producer thread goes to wait state (and releasing the lock) and then consumer thread which has been in runnable states gets the lock (after producer releases it), consumes the object, notify the producer to produce another and same cycle repeats for the 3 times.

That's all for the solution of producer consumer problem using wait and notify method with the help of above code example. If you have any question. please feel free to ask in comment section.

Sunday, September 4, 2016

Java Multi-threading Interview Questions and Answers - Series I

Java Multi-threading is quite tricky to understand. But if you understand its basics clearly, all other aspects to understand become so easy. Here are the first series of Java Multi-threading Interview Questions and Answers.

What are the different ways to create Threads in Java?

There are three ways to create threads in Java:
(a) By implementing runnable interface
(b) By extending Thread Class
(c) Using ThreadPoolExecutor to create one or more threads

Why the wait and notify methods are part of Object class and not Thread class?

For thread to go on wait state, its requires that it should wait on a particular Java Object so that the same object can be notified to make the thread back to runnable state. 

What is difference between wait and notify

wait method of Object class put the calling thread into wait state from running state whereas notify method put the waiting thread back to runnable state.

Tell me the difference between notify and notifyAll method

Suppose there are more than one threads waiting on an object, if we call notify method, only one thread will be back to runnable state out of n waiting threads. So the number of waiting threads will be  n - 1
notifyAll method will wake up all the threads waiting on an Object to the runnable state.

What is the benefit of concurrent classes

Java 5 provides a series of concurrent classes like ConcurrentHashMap and others, the benefit of which is that we can access those data-strucure classes simultaneously by multiple threads parallely without worrying about thread synchronization and we don't have to wait for one task to complete to start another.

How is HashMap different from ConcurrentHashMap

HashMap is not threadsafe i.e. the developer needs to take care of synchronization if multiple threads are accessing the HashMap whereas in Concurrent HashMap we dont have to worry about synchronization if multiple threads are accessing it.
Moreover, with no sychrnoziation overhead to be created by developer, ConcurrentHashMap is much faster than HashMap (considering we need to implement synchornization mechanism to work with HashMap)

Hashtable and ConcurrentHashMap both are threadsafe, which one  you will prefer

I will prefer ConcurrentHashMap because its performance is much faster as compared to Hashtable as all the methods of Hashtable are synchronized, there is overhead for acquiring and releasing object locks in Hashtable.
With multiple processor in place, apart from synchronization overhead, if multiple threads are calling the same method (for eg. put method), ConcurrentHashMap calls can go parallely and Hashtable calls needs to be executed synchronously.

How does String class is threadsafe if its internal implementation is not synchronized

String is a immutable class, so its value once set via constructor, it will not change and so all threads will see the same value and can be used across threads. This is true for every immutable class and we dont require synchronization to make it threadsafe. In other words, immutable class like String is a constant, so it can be safely used by multiple threads without fearing the change of value by one and dirty read by another (which is not possible here).

Do you need to hold lock of the object before you call Object.wait() or Object.notify()

Yes, for any call to wait and notify method, the calling thread must have the monitor lock with it. If we call it without having the monitor lock, it will throw exception.

If yes, then will Object.wait() will keep the lock forever

No, calling to Object.wait() will put the current thread in wait state waiting for notify on that object and release the lock by current thread immediately.

What is Deadlock

Deadlock is the situation where one thread is holding a resource and waiting for another resource and the other thread is holding that another resource and waiting for a resource. This situation is called deadlock.

What is Atomic in java

Java 5 introduce Atomic Variable such as AtomicInteger, AtomicLong and others. The benefit of using Atomic classes is that its operation cannot be interrupted in between. For example, i++ is a three step operation, fetching value of i from memory, increasing its value and putting back new value of i in memory. Any other thread can interrupt in between three calls whereas with Atomic classes it is just a one cpu call (all three combined), so a similar operation like i++ in AtomicInteger cannot be interrupted.

Will declaring a variable as volatile makes it a threadsafe

No, declaring a variable as volatile will only make sure that the it will always reads the memory value of variable and not the local thread cache. This means that if some other thread has updated the value, the current thread will only read the updated one (local cache copy may be dirty in this case). This in no case will make it threadsafe because changes by two threads can be overwritten by each other even though both threads are reading the in-memory data.
The benefit of using volatile in multi-threaded environment is that if one thread is making changes to a variable and other threads are only reading it, the changes made by that thread will be immediately visible to other threads.

That's all for Series -I of Core Java Multi-threading Interview Questions with Answers. If you are looking for all Java Interview questions, here is the link.