Showing posts with label Java Multithreading. Show all posts
Showing posts with label Java Multithreading. Show all posts

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.

Thursday, February 18, 2016

Java Equals Hashcode Contract Example

This the one of the most common question we used to face during Core Java interview, however its understanding is bit tricky. I will rather take unique approach to make the understanding simple.

So, what is the contract between hashcode and equals to be used as a key to HashMap / HashSet?

Java specification says that if you want to use any object as key to a hashmap or hashset or any other hashing, the contract is that
If two objects are equal according to the equals method, then its hashCode method on each of the two objects must return the same integer result.

Why so?

To understand why this contract even come into picture, we need to understand how hashmap works. Usually in best possible scenario, the time complexity to retrieve an object from hashmap is o(1). In other words, if you ask to retrieve an object by providing key from a map of millions, it just know where exactly it is and goes directly to that object and fetch it without iterating other objects. Thats the beauty of hashing technique.

Hashing Technique:

To understand hashing technique in simple terms, consider you have written a letter to me to be delivered.
Does the postman passes goes to each person and ask his name to find me?
Definitely not. He sends your post to the pincode and then it searches among the pincode. Since in best possible scenario, there is only one person per pincode, the letter reaches to me directly. This the way hashing technique works.
When you store an object to an hashmap, its stores on the key hashcode (also known as bucket). So, while retrieving in one shot, it requires the key hashcode again and thats why it is required to have same hashcode integer result every time. If it is going to give different hashcode, HashMap stores element on different code/bucket and trying to retrieve from different code/bucket, hence unable to retrieve object even-if it is present in hashmap on different bucket / hashcode / pincode.

Java Interview Questions on Atomic variables

Here are the list of 5 good questions on Volatile and Synchronized keywords in Java:

1. What is Atomic variables and its significance:

Atomic variables performs atomic operation on its object. In other words, it operation will happen completely or will not happen at all, and no one can interrupt its operation in between. With its introduction in Java 1.5, it is being widely used in multi-thread environment without any synchronization.

2. Is Atomic variable more faster or variable through synchronized code?

For read access, it does not matter whether it is atomic or non-atomic, synchronized or non-synchronized. For write access, atomic variable does not require lock to write because all update to variable happens atomic (either happened or not happened completely) For eg: suppose you want to do i++ in a multi-threaded application and multiple threads can call this, you need to synchronized i++ call (as it is set to 3 registry levels call and you know it can be context switch at any point of registry level calls even in between) to avoid dirty reads and inconsistent write. Atomic variable has just 1 registry level calls.

3. What is the disadvantage of Atomic variables as compared to its primitive type?

All Objects in java requires more care by the programmer to avoid memory consistency errors, doesnt matter whether it is Atomic or not. While the siblings of Atomic variable can be primitive and not object, it doesn't falls into object category and hence not required to take care of memory consistency error The reason why every object requires to avoid memory consistency errors in multi-threaded application is because each thread stack caches the copy of object locally on thread stack (Runtime optimization) might result into not in sync with actual copy of heap if it gets modified by another thread (even in the same code but different thread stack). One solution to avoid is to use volatile for that object which can be changed by another thread frequently. Also the local copy tries to in sync with heap copy very fast but problem occurs if your thread access it more faster than sync happens.

4. How Atomic variables are implemented internally or how atomic variables achieves atomicity?

With the introduction of additional register being added to cpu, atomic variables harness it to achieve atomicity. Since its just 1 cpu register call, it cannot be interrupted in between.

5. What are the atomic variable classes in java?

There are only two classes: AtomicInteger and AtomicLong. There is no atomic level classes for other primitives like double, float etc.

Wednesday, February 10, 2016

Daemon Thread in java

Introduction:

In Java, Daemon Threads are one of the types of thread which does not prevent Java Virtual Machine (JVM) from exiting.
The main purpose of daemon thread is to execute background task especially in case of some routine periodic task or work. With JVM exits, daemon thread also dies.

How to create a Daemon Thread in Java:

By setting a thread.setDaemon(true), a thread becomes a daemon thread. However, you can only set this value before the thread start.

Code Example:


public class DaemonThread {

public static void main(String[] args) {
System.out.println("Entering Main Thread");
Thread t = new Thread(new Runnable(){
@Override
public void run() {
for(int i=0; i<5; i++) {
System.out.println("Executing Daemon Thread");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.setDaemon(true); // Thread becomes daemon thread here
t.start();
System.out.println("Exiting Main Thread");
}
}

Here is the sample output:

Output1:
Entering Main Thread
Exiting Main Thread

Output2:
Entering Main Thread
Exiting Main Thread
Executing Daemon Thread
Executing Daemon Thread

Explanation

In the above code example, main thread is spawning a daemon thread, Here main thread is the only non-deamon thread. As soon as the main thread execution completes, JVM exits and daemon thread dies alongwith.

The above code example and output illustrates the following:
  • JVM doesn't wait for the daemon thread to complete its task
  • Daemon thread dies as soon as JVM exits

Finding if the thread is daemon or not:

To know if a thread is daemon or not, you can check with Thread.isDeamon(). If returns true, the thread is daemon.