Table of Contents
ToggleWe’ll go through Multithreading Java Interview Questions and Answers today. Because multithreading and concurrency go hand in hand, we will also look at Concurrency and threads interview questions and answers.
Thread is a common and popular subject in java interview questions for freshers as well as experienced developers. From an interview viewpoint, I’ve compiled a list of the most significant multithreading java interview Questions
1. What is the meaning of concurrency?
Concurrency refers to the ability for a program or process to simultaneously execute multiple computations. This is possible by spreading the computations across the CPU cores of the machine, or over multiple machines in the same network.
2. What’s the difference between threads and processes?
A process is an execution environment that the operating system provides. It has its own set private resources (e.g. memory, open files, etc.). Contrary to processes, threads live in a process and share resources (memory open files etc.). With other threads in the process. Threads that can share resources with other threads are more suitable for tasks that require high performance.
3. What is a Scheduler?
A scheduler is a program that implements a scheduling algorithm to manage access to processes and threads to a limited resource, such as the processor or I/O channel. Most scheduling algorithms aim to provide load balancing to ensure that all processes/threads have access to the resource in the appropriate time.
4. What’s the purpose of thread groups and why are they important?
Each thread belongs to one of a number of threads. The JDK class java.lang.ThreadGroup provides some methods to handle a whole group of Threads. These methods allow us to interrupt all threads in a group and set their maximum priority.
5. What is the thread lifecycle in Java?
- NEW : This state is where a thread has yet to start.
- RUNNABLE : A thread that executes in the Java virtual machine’s Java virtual machine is currently in this state.
- BLOCKED : A thread is currently in this state, waiting for a lock to be installed.
- WAITING : is a thread that waits indefinitely for another thread perform a specific action.
- TIMED_WAITING : A thread is in this state while it waits for another thread’s action for a certain time.
- TERMINATED : A thread has been terminated.
6. Is it possible for a thread to be started twice?
No, after invoking the thread’s start() method, another invocation of start() will throw an illegalThreadStateException.
7. What is best practice to handle InterruptedException?
Methods such as sleep() or join() throw an InterruptedException, which tells the caller that another thread is interrupting this thread. This is usually done to inform the current thread to stop all its computations and finish them unassisted. This is why ignoring an exception and logging it to the console, or a log file, is not the best way to deal with this type of exception. This exception is problematic because the Runnable interface method run() does not allow run() to throw any exceptions. It is not possible to rethrow it. This means that run() must handle the checked exception. It is often caught and ignored.
8. How to implement deadlock detection?
If all locks are monitored and modeled as a directed graph then a deadlock detection system will search for threads that are waiting on each other to unlock a resource it has locked. To force the other thread to unlock the lock, the waiting threads can be made to accept an exception.
9. What are the conditions for a deadlock?
The following are the requirements to be in a deadlock:
- Mutual exclusion: A resource can only be accessed by one thread at a time.
- Resource holding: The thread attempts to lock another resource while it has locked one.
- No preemption: There is no preemption if one thread holds the lock for a certain period of time, there is no mechanism that will free the resource.
- Circular wait: I is a situation in which two or more threads wait for the other thread to unlock a resource it has locked.
10. How to prevent Deadlocks?
To prevent deadlocks, one or more of these requirements must be removed.
- Mutual exclusion: It is possible to avoid mutual exclusion in certain situations by using optimistic locking.
- Resource holding: When a thread fails to obtain all the exclusive locks it wants, it may be able to release all of its exclusive locks.
- No preemption: A timeout to lock an exclusive device unlocks it after a certain time.
- Circular wait: If all locks are obtained using the same threads, there is no circular wait.
11. What is a Livelock?
A livelock is when two or more threads are unable to respond to the actions of another thread. Contrary to a deadlock situation where several threads wait in a specific state, a livelock involves threads who change their state so that they can’t make progress with their regular work. A situation where two threads attempt to acquire two locks but can’t acquire the second lock, would be an example. Both threads may attempt to acquire the first one concurrently. If only one thread succeeds in acquiring the lock, the second thread might succeed in acquiring it. Both threads now have two locks. However, as they both desire to have both locks both release their locks and retry the process from the beginning. This could happen again and again.
12. What’s the difference between notify() and notifyAll()?
Both methods can be used to wake up threads that have been asleep by calling wait(). Notify() can only wake up one waiting thread, but notifyAll() will wake up all of them.
13. What is Thread.yield()?
Invoking the static method Thread.yield() will give the scheduler an indication that the current thread is ready to release the processor. This hint is not binding on the scheduler. It is possible that the thread currently being executed becomes the “next” thread, even though Thread.yield() cannot be defined.
14. Explain the use of class java.lang.ThreadLocal?
ThreadLocal allows you to store and retrieve individual thread values, as memory is shared among different threads. ThreadLocal implements threads independently to store and retrieve values. Thread A stores A1 while thread B stores B1 in the ThreadLocal instance. Thread A retrieves A1 later from the ThreadLocal instance, and thread B retrieves B1.
15. Explain relationship between Executor and ExecutorService.
Executor is the interface that defines only one method. This interface’s implementations will need to execute the Runnable instance specified at some point in the future. The ExecutorService interface extends the Executor interface. It provides additional methods for shutting down the underlying implementation and waiting for the termination of all tasks. It also allows you to submit instances of Callable.
16. What is difference between Runnable and Callable?
The interface Runnable describes the method run() with no return value, whereas the interface callable allows run() to return a return value and throw an exception.
17. What is a Semaphore?
A semaphore refers to a data structure that holds a list of permits that must be acquired by different threads. Semaphores are used to limit the number of threads that can access a resource or section at once. Hence the constructor of java.util.concurrent.Semaphore takes as first parameter the number of permits the threads compete about. Each of the acquire() methods attempts to obtain one of these permits. The method acquire() does not require any parameter blocks, until the next permit becomes available. When the thread is done working on the critical resource, the thread can release the permit later by calling the method release() on an instance Semaphore.
18. Explain Fork/Join framework
The base class of the Fork/Join Framework java.util.concurrent.ForkJoinPool is basically a thread pool that executes instances of java.util.concurrent.ForkJoinTask. ForkJoinTask contains the methods join() and fork(). Fork() is used for the synchronous execution of the task. Join() is used to wait for the results of the computation. The Fork/Join framework is useful for implementing divide-and-conquer algorithms, where a more difficult problem can be divided into smaller, easier-to-solve problems.
19. What are applications of java.lang.ThreadLocal class?
ThreadLocal instances can be used to transfer information from one application to another. One example would be to transport security/login information within ThreadLocal so that it can be accessed by all methods. Another example would be the transportation of transaction information, or general objects, that should be available in all methods and not be passed from one method to another.
20. Explain by an example the technique lock splitting.
Lock splitting can be used to reduce lock contention, when one lock is used for synchronizing access to different parts of an application. Let’s say we have a class that computes some statistical data for our application. To protect the internal state from corruption by concurrent threads, a first version of the class uses the keyword synchronized within each method signature. Lock contention can result from multiple threads trying to obtain the same lock at once. It may be possible to divide the lock on an object instance into smaller locks for each type or statistical data within each method. Thread T1 can increment statistical data D1 without waiting for the lock to be released. While thread T2 updates D2, thread T1 is able to do the same.
21. How is a thread created in Java?
Basically, there are two ways to create a thread in Java.
The first one is to write a class that extends the JDK class java.lang.Thread and call its method start():
public class MyThread extends Thread { public MyThread(String name) { super(name); } @Override public void run() { System.out.println("Executing thread "+Thread.currentThread().getName()); } public static void main(String[] args) throws InterruptedException { MyThread myThread = new MyThread("myThread"); myThread.start(); } }
The second way is to implement the interface java.lang.Runnable and pass this implementation as a parameter to the constructor of java.lang.Thread:
public class MyRunnable implements Runnable { public void run() { System.out.println("Executing thread "+Thread.currentThread().getName()); } public static void main(String[] args) throws InterruptedException { Thread myThread = new Thread(new MyRunnable(), "myRunnable"); myThread.start(); } }
22. How do we stop a thread in Java?
The stop() method of thread class terminates the thread execution. Once a thread is stopped, it cannot be restarted by start() method.
public class JavaStopExp extends Thread { public void run() { for(int i=1; i<5; i++) { try { sleep(500); System.out.println(Thread.currentThread().getName()); }catch(InterruptedException e){System.out.println(e);} System.out.println(i); } } public static void main(String args[]) { // creating three threads JavaStopExp t1=new JavaStopExp(); JavaStopExp t2=new JavaStopExp(); JavaStopExp t3=new JavaStopExp(); // call run() method t1.start(); t2.start(); // stopping t3 thread t3.stop(); System.out.println("Thread t3 is stopped"); } }
23. What is daemon threads in java?
A daemon thread is a low priority thread whose execution state is not evaluated when the JVM decides if it should stop or not, hence they keep running in background. The JVM stops when all user threads (in contrast to the daemon threads) are terminated. Hence daemon threads can be used to implement for example monitoring functionality as the thread is stopped by the JVM as soon as all user threads have stopped:
public class Example { private static class MyDaemonThread extends Thread { public MyDaemonThread() { setDaemon(true); } @Override public void run() { while (true) { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) throws InterruptedException { Thread thread = new MyDaemonThread(); thread.start(); } }
24. Explain busy waiting.
Busy waiting refers to implementations that wait for an event by executing certain active tasks that allow the thread/process to occupy the processor despite the fact that the scheduler may remove it from it. A busy waiting example would be to spend the waiting time within a loop that determines the current time repeatedly until a specific point in time is reached:
Thread thread = new Thread(new Runnable() { @Override public void run() { long millisToStop = System.currentTimeMillis() + 5000; long currentTimeMillis = System.currentTimeMillis(); while (millisToStop > currentTimeMillis) { currentTimeMillis = System.currentTimeMillis(); } } });
25. What is a shutdown hook?
A shutdown hook is a thread that gets executed when the JVM shuts down. It can be registered by invoking addShutdownHook(Runnable) on the Runtime instance:
Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() {} });
Final Note
Multithreading is one of the important concepts when developing applications in java.To handle vast amount of tasks, multithreading becomes one of the important skill that interviewer would look upon in any java developer.The above must do multithreading java interview questions will definitely help you prepare and ace the interviews for java developer.