Java Multithreading Interview Questions and Answers

Java Multithreading Interview Questions and Answers

Like Collections, Multithreading is also an important topic in Java. Whether you are a fresher or experienced, if you go to any Java interview, you will get at least one question from concurrency and multi-threading in Java. In this post we will see some of the frequently asked Java Multithreading interview questions and answers. I would recommend you to read the books Effective Java and Java Concurrency in Practice to get good understanding of multi-threading and concurrency in Java.

1. What is Thread in Java?

A thread is a lightweight sub process. It is an independent path of execution. A thread is executed inside a process and one process can have multiple threads.  All the threads inside a process shares a common memory area.  Since threads are independent, if an exception occurs in one thread, it doesn’t affect other threads. Threads are used to take advantage of multiple CPU cores available in a machine.

2. What is the difference between Thread and Process in Java?

A process is a program in execution. It can also be defined as a self contained execution environment. A Thread is a single task of execution within the process. One process can have multiple threads. A process has its own memory space. A thread uses the process’s memory space and share it with the other threads inside the process.

3. What are the ways to create a Thread in Java?

This is one of the frequently asked interview questions.

There are two ways to create a Thread in Java – By extending java.lang.Thread class or by implementing java.lang.Runnable interface. In both the case, you can provide implementation in the run() method.

Example:

ThreadClassExample.java

RunnableInterfaceExample.java

4. Implementing Runnable interface vs extending Thread class in Java.

This is a follow-up of previous question. The interviewer may ask when to use Runnable interface and when to use Thread class and which one is better?

  • In Object oriented programming extending a class generally means adding new functionality, modifying or improving behaviors. So you must extend the Thread class only when you are looking to use other properties and methods of Thread class apart from implementing the run() method. If you are simply looking to modify only the run() method, implementing Runnable interface is the best option (Runnable interface has only one abstract method i.e. run()).
  • Since Multiple inheritance is not allowed in Java, it is better to implement Runnable interface so that we can extend some other class as well.
  • Implementing Runnable is lightweight operation because when we extend Thread class, all Thread features are inherited, but when we implement Runnable interface no extra features are inherited, as Runnable consists only one abstract method i.e. run(). So, implementing Runnable is a lightweight operation.
  • Runnable interface represent a Task and once a runnable object is created, it can be reused to create any number of threads. Executors also accepts Runnable object as Task. So a runnable task can be executed either by plain Thread or Executor’s worker thread.

5. Explain the life cycle of a Thread or What are the different states of a Thread?

When you are programming with threads, understanding the life cycle of thread is very valuable. While a thread is alive, it is in one of several states. By invoking start() method, it doesn’t mean that the thread has access to CPU and start executing straight away. Several factors determine how it will proceed.

Different states of a thread are:

life cycle of thread in Java

  1. New state – After the creations of Thread instance the thread is in this state but before the start() method invocation. At this point, the thread is considered not alive.
  2. Runnable (Ready-to-run) state – A thread start its life from Runnable state. A thread first enters runnable state after the invoking of start() method but a thread can return to this state after either running, waiting, sleeping or coming back from blocked state also. On this state a thread is waiting for a turn on the processor.
  3. Running state: A thread is in running state that means the thread is currently executing. There are several ways to enter in Runnable state but there is only one way to enter in Running state: the scheduler select a thread from runnable pool.
  4. Dead state – A thread can be considered dead when its run() method completes. If any thread comes on this state that means it cannot ever run again.
  5. Blocked – A thread can enter in this state because of waiting for the resources that are hold by another thread.

Different states in a Multiple-Threaded environment

 

Multiple Thread states

As we have seen different states that may be occur with a single thread. A running thread can enter to any non-runnable state, depending on the circumstances. A thread cannot enter directly to the running state from non-runnable state, firstly it goes to runnable state. Now lets understand the some non-runnable states which may be occur handling multiple threads.

  • Sleeping –  On this state, the thread is still alive but it is not runnable, it might return to runnable state later, if a particular event occurs. On this state, a thread sleeps for a specified amount of time. You can use the method sleep() to stop the running state of a thread.
  • Waiting for Notification – A thread waits for notification from another thread. The thread sends back to runnable state after sending notification from another thread.
  • Blocked on I/O – The thread waits for completion of blocking operation. A thread can enter on this state because of waiting I/O resource. In that case the thread sends back to runnable state after availability of resources.
  • Blocked for joint completion – The thread can come to this state because of waiting for the completion of another thread.
  • Blocked for lock acquisition – The thread can come to this state because of waiting to acquire the lock of an object.

6. What is a Daemon thread?

Daemon threads are non-user threads. They are typically used to carry out low-priority tasks that should not take priority over the main task of the program. They can be used to do useful work when all other user threads are blocked. The garbage collector is one example of a daemon thread.

JVM terminates itself when all non-daemon threads (user threads) finishes their execution, JVM does not care even if some Daemon threads are running. If JVM finds running daemon thread (upon completion of user threads), it terminates the thread and after that shutdowns itself. You can make a user thread to Daemon by using setDaemon() method of thread class.

A child thread created from daemon thread is also a daemon thread.

7. What is difference between user Thread and daemon Thread?

By default a thread created in a Java program is always a user thread however we can make it daemon by calling setDaemon(true) method, if needed. A daemon thread runs in the background and doesn’t prevent JVM from terminating. As soon as all user thread finishes execution, Java program or JVM terminates itself, JVM doesn’t wait for daemon thread to finish their execution. As soon as last non daemon thread finished, JVM terminates no matter how many Daemon thread exists or running inside JVM.

8. Can we call run() method of a Thread class?

Yes, we can call run() method of a Thread class but it will behave like a normal method and a new thread will not be created to execute the run() method. In this case the run() method will be executed in the same thread which called the run method. To actually execute it in a new Thread, we need to start it using Thread.start() method.

9. How does thread communicate with each other?

Threads can communicate using wait(), notify() and notifyAll() methods. Read this post to understand inter thread communication.

10. What is Deadlock? How to analyze and avoid deadlock situation?

In an operating system, a deadlock is a situation which occurs when a process or thread enters a waiting state because a resource requested is being held by another waiting process, which in turn is waiting for another resource. If a process is unable to change its state indefinitely because the resources requested by it are being used by another waiting process, then the system is said to be in a deadlock.

In programming, deadlock occurs with two or more threads blocked forever, with two or more resources.

To analyze a deadlock, we need to look at the Java thread dump(heap dump) of the application, we need to look out for the threads with state as BLOCKED and then the resources it’s waiting to lock, every resource has a unique ID using which we can find which thread is already holding the lock on the object.

Avoiding nested locks, locking only what is required and avoiding waiting indefinitely are common ways to avoid deadlock situation, read this post to learn how to analyze deadlock in java with sample program.

11. Explain about Thread Priority?

Every thread has a priority, usually higher priority thread gets precedence in execution but it depends on Thread Scheduler implementation that is OS dependent. We can specify the priority of thread using Thread’s setPriority(int) method but it doesn’t guarantee that higher priority thread will get executed before lower priority thread. Thread priority is an int whose value varies from 1 to 10 where 1 is the lowest priority and 10 is the highest priority.

12. Difference between wait() and sleep() methods.

wait()sleep()
wait() is a method from Object classsleep() is a static method of Thread class
wait() method release the lock when thread is waiting.sleep() will only pause the thread for some time and keep the lock.
wait method should be called from synchronized block or method else it will throw IllegalMonitorStateExceptionThere is no such requirement and sleep can be called anywhere
To wake a thread from wait(), you have to call notify() or notifyAll() methodWhile in sleep (), thread gets start after the specified duration

13. What is volatile in Java?

volatile is a special modifier which is used to indicate that a variable’s value will be modified by different threads. The volatile keyword will mark a Java variable as “being stored in main memory”. The value of this variable will never be cached locally: all reads and writes will go straight to “main memory”. Volatile variable guarantees that a write will happen before any subsequent read. Access to the variable acts as though it is enclosed in a synchronized block.

14. Write Java program to solve Producer Consumer problem.

Ans.

15. What does yield method of Thread class do?

yield() method causes the currently executing thread object to temporarily pause and allow other threads to execute. If there is no waiting thread or all the waiting threads have a lower priority than the current thread, then the same thread will continue its execution. When the yielded thread will get the chance for execution is decided by the thread scheduler whose behavior is platform dependent.

16. What does the join() method in Thread class do?

The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing, t.join() causes the current thread(the thread which calls t.join(), mostly the main thread) to pause execution until t’s thread terminates.

17. What do you mean by synchronization and what is the level of synchronization that can be applied?

Synchronization is nothing but control of access to a shared resource among multiple threads. Without synchronization when multiple thread try to access a shared resource there may arise unforeseen result due to concurrency issue. For example if multiple threads try to write within a same file then the file may be corrupted because one of the threads can overwrite data of other or while one thread is opening the file, at the same time another thread might be closing the file. So there is a need to control access to a shared resource such that only one thread can operate at a given time. Synchronization in java is achieved using synchronized keyword.

Synchronization can be applied to methods and blocks in a class.

Synchronized Method Example:

If you remove the synchronized keyword from the print method and run the program, the output will be different in different execution. Below is the output that is obtained in one of the executions.

It is evident from the above output that, without synchronization, both the threads access the print() method simultaneously.

Synchronized Block Example:

The level of synchronization in the above example can also be achieved by using synchronized block. A synchronized block is nothing but a group of statements within curly braces with a synchronized keyword.

When you run the above program you will get the same output as that of synchronized method example. Here synchronization is achieved by obtaining a lock on the display object d. So at a particular point of time only one thread can access methods of the object d. So when the program is run, Thread-1 gets a lock on object d and Thread-2 has to wait until Thread-1 finishes.

18. What is the difference between notify() and notifyAll()?

notify() method wakes up a single thread that is waiting on this object’s monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is random and occurs at the discretion of the implementation. notifyAll() wakes up all threads that are waiting on this object’s monitor. A thread waits on an object’s monitor by calling one of the wait methods.

19. Can we start a thread twice in Java?

No, once a thread is started, it can never be started again. Doing so will throw an IllegalThreadStateException.

Let us understand it by an example given below

Output:

As seen from the above output, when the thread started for the first time, it prints “Thread-0 is executing.” and the second invocation of start() throws an exception.

20. How can you ensure all threads that started from main must end in order in which they started?

We can use join() method to ensure all threads that started from main will end in order in which they started and also main should end in last.

21. Why thread communication methods wait(), notify() and notifyAll() are in Object class?

In Java, wait and notify methods acts as synchronization utility and are essential methods for inter thread communication. Hence these methods are defined in Object class so that every object will have access to it. Also every Object has a monitor and Locks are made available on per Object basis. This is another reason why wait and notify is declared in Object class rather then Thread class.

22. Can a constructor be synchronized?

No, constructor cannot be synchronized. Constructor is used for instantiating object and when we are in constructor, object is under creation. So, until object is not instantiated it does not need any synchronization.

23. How can you access the current thread in Java?

The current thread can be accessed by calling the static method currentThread() of the java.lang.Thread class. E.g. Thread.currentThread().getName().

24. What happens when an uncaught exception occurs in the run() method?

When an unchecked exception has occurred in the run() method, the thread is stopped by the Java Virtual Machine. It is possible to catch this exception by registering an instance that implements the interface UncaughtExceptionHandler as an exception handler. The handler can be registered by invoking the static method Thread.setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler) or by invoking setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler) on the thread instance which tells the JVM to use the provided handler in case there was no specific handler registered on the thread.

25. What do you mean by an atomic operation?

In programming, an atomic operation is one that effectively happens all at once. An atomic operation cannot stop in the middle: it either happens completely, or it doesn’t happen at all. No side effects of an atomic operation are visible until the action is complete.

In Java,

  • Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double).
  • Reads and writes are atomic for all variables declared volatile (including long and double variables).
  • all operations of java.concurrent.Atomic* classes

Atomic actions cannot be interleaved, so they can be used without fear of thread interference. However, this does not eliminate all need to synchronize atomic actions, because memory consistency errors are still possible.

 26. What happens when start() method is called?

A new thread of execution with a new call stack is created. The state of thread changes from new to runnable. When the thread gets chance to execute, its target run() method starts to run.

That’s all about Java multithreading interview questions and answers. If you have any doubt, post it in the comments section.

Also see,

Frequently asked Java collection interview questions and answers

Frequently asked Java String interview questions and answers

The following two tabs change content below.
Working as a Java developer since 2010. Passionate about programming in Java. I am a part time blogger.
2 comments
  1. Thanks for the useful article. Just one clarification, I think the 1st figure under 5th question showing the states of a single thread is wrong. Please have a look.

Add Comment

Required fields are marked *. Your email address will not be published.