Top 40 Java Threads Interview Questions You Must Prepare 19.Mar.2024

Threads can communicate with each other by using wait(), notify() and notifyAll() methods.

We can use join() methodto ensure all threads that started from main must end in order in which they started and also main should end in last.In other words waits for this thread to die. Calling join() method internally calls join(0);
DETAILED DESCRIPTION : Join() method - ensure all threads that started from main must end in order in which they started and also main should end in last. Types of join() method with programs- 10 salient features of join.

 

 

When thread does not enough CPU for its execution Thread starvation happens.
Thread starvation may happen in following scenarios >
•Low priority threads gets less CPU (time for execution) as compared to high priority threads. Lower priority thread may starve away waiting to get enough CPU to perform calculations.
•In deadlock two threads waits for each other to release lock holded by them on resources. There both Threads starves away to get CPU.
•Thread might be waiting indefinitely for lock on object’s monitor (by calling wait() method), because no other thread is calling notify()/notifAll() method on object. In that case, Thread starves away to get CPU.
•Thread might be waiting indefinitely for lock on object’s monitor (by calling wait() method), but notify() may be repeatedly awakening some other threads. In that case also Thread starves away to get CPU.

 

1.Every Object has a monitor, acquiring that monitors allow thread to hold lock on object. But Thread class does not have any monitors.
1.wait(), notify() and notifyAll()are called on objects only >When wait() method is called on object by thread it waits for another thread on that object to release object monitor by calling notify() or notifyAll() method on that object.
When notify() method is called on object by thread it notifies all the threads
which are waiting for that object monitor that object monitor is available now.
So, this shows that wait(), notify() and notifyAll() are called on objects only.
Now, Straight forward question that comes to mind is how thread acquires object lock by acquiring object monitor? Let’s try to understand this basic concept in detail?
1.Wait(), notify() and notifyAll() method being in Object class allows all the threads created on that object to communicate with other.
2.As multiple threads exists on same object. Only one thread can hold object monitor at a time. As a result thread can notify other threads of same object that lock is available now. But, thread having these methods does not make any sense because multiple threads exists on object its not other way around (i.e. multiple objects exists on thread).
3.Now let’s discuss one hypothetical scenario, what will happen if Thread class contains wait(), notify() and notifyAll() methods?
Having wait(), notify() and notifyAll() methods me Thread class also must have their monitor.
Every thread having their monitor will create few problems -
>Thread communication problem.
>Synchronization on object won’t be possible- Because object has monitor, one object can have multiple threads and thread hold lock on object by holding object monitor. But if each thread will have monitor, we won’t have any way of achieving synchronization.
>Inconsistency in state of object (because synchronization won't be possible).

 

notifyAll() method moves all waiting threads from the waiting pool to ready state.

holdsLock(object) method can be used to find out whether current thread holds the lock on monitor of specified object.
holdsLock(object) method returns true if the current thread holds the lock on monitor of specified object.

 

One process can have multiple Threads,Thread are subdivision of Process. One or more Threads runs in the context of process. Threads can execute any part of process. And same part of process can be executed by multiple Threads.
Processes have their own copy of the data segment of the parent process while Threads have direct access to the data segment of its process.Processes have their own address while Threads share the address space of the process that created it.
Process creation needs whole lot of stuff to be done, we might need to copy whole parent process, but Thread can be easily created.Processes can easily communicate with child processes but interprocess communication is difficult. While, Threads can easily communicate with other threads of the same process using wait() and notify() methods.
In process all threads share system resource like heap Memory etc. while Thread has its own stack.Any change made to process does not affect child processes, but any change made to thread can affect the behavior of the other threads of the process.Example to see where threads on are created on different processes and same process.

When a Thread calls the sleep() method, it will return to its waiting state. When a  Thread calls the yield() method, it returns to the ready state.

A very simple way to avoid deadlock while using N threads is to impose an ordering on the locks and force each thread to follow that ordering. Thus, if all threads lock and unlock the mutexes in the same order, no deadlocks can arise.

When you call start() method, main thread internally calls run() method to start newly created Thread, so run() method is ultimately called by newly created thread.
When you call run() method main thread rather than starting run() method with newly thread it start run() method by itself.

No, we cannot start Thread again, doing so will throw runtimeException java.lang.IllegalThreadStateException. The reason is once run() method is executed by Thread, it goes into dead state.
Let’s take an example-
Thinking of starting thread again and calling start() method on it (which internally is going to call run() method) for us is some what like asking dead man to wake up and run. As, after completing his life person goes to dead state.

The java.lang.Object class wait() method throws "InterruptedException".

 

Yes, it’s mandatory to acquire object lock before calling these methods on object. wait(), notify()  and notifyAll() methods are always called from Synchronized block only, and as soon as thread enters synchronized block it acquires object lock (by holding object monitor). If we call these methods without acquiring object lock i.e. from outside synchronize block then java.lang. IllegalMonitorStateException is thrown at runtime.
Wait() method needs to enclosed in try-catch block, because it throws compile time exception i.e. InterruptedException.

No, constructor cannot be synchronized. Because constructor is used for instantiating object, when we are in constructor object is under creation. So, until object is not instantiated it does not need any synchronization.
Enclosing constructor in synchronized block will generate compilation error.
Using synchronized in constructor definition will also show compilation error.
COMPILATION ERROR = Illegal modifier for the constructor in type ConstructorSynchronizeTest; only public, protected & private are permitted
Though we can use synchronized block inside constructor.

The JVM uses locks in conjunction with monitors. A monitor is basically a guardian that watches over a sequence of synchronized code and ensuring that only one thread at a time executes a synchronized piece of code. Each monitor is associated with an object reference. The thread is not allowed to execute the code until it obtains the lock.

 

There are three ways that can be used in order for a Thread to be created:
• A class may extend the Thread class.
• A class may implement the Runnable interface.
• An application can use the Executor framework, in order to create a thread pool.
The Runnable interface is preferred, as it does not require an object to inherit the Thread class. In case your application design requires multiple inheritance, only interfaces can help you. Also, the thread pool is very efficient and can be implemented and used very easily.

Differences yield() and sleep() :
Definition : yield() method when called on thread gives a hint to the thread scheduler that the current thread is willing to yield its current use of a processor.The thread scheduler is free to ignore this hint. sleep() methods causes current thread to sleep for specified number of milliseconds (i.e. time passed in sleep method as parameter). Ex- Thread.sleep(10) causes currently executing thread to sleep for 10 millisec.
Thread state : when sleep() is called on thread it goes from running to waiting state and can return to runnable state when sleep time is up. when yield() method is called on thread it goes from running to runnable state, not in waiting state. Thread is eligible to run but not running and could be picked by scheduler at anytime.
Exception : yield() method need not to catch or throw any exception. But sleep() method must catch or throw compile time exception i.e. InterruptedException.
Waiting time : yield() method stops thread for unpredictable time, that depends on thread scheduler. But sleep() method have got few options.
1.sleep(long millis) - Causes the currently executing thread to sleep for the specified number of milliseconds
2.sleep(long millis, int nanos) - Causes the currently executing thread to sleep for the specified number of milliseconds plus the specified number of nanoseconds.
similarity between yield() and sleep():
> yield() and sleep() method belongs to java.lang.Thread class.
> yield() and sleep() method can be called from outside synchronized block.
> yield() and sleep() method are called on Threads not objects.

wait() method releases CPU, releases objects lock, the thread enters into pool of waiting threads.

  • Threads consumes CPU in best possible manner, hence enables multi processing. Multi threading reduces idle time of CPU which improves performance of application.
  • Thread are light weight process.
  • A thread class belongs to java.lang package.
  • We can create multiple threads in java, even if we don’t create any Thread, one Thread at least  do exist i.e. main thread.
  • Multiple threads run parallely in java.  
  • Threads have their own stack.
  • Advantage of Thread : Suppose one thread needs 10 minutes to get certain task, 10 threads used at a time could complete that task in 1 minute, because threads can run parallely.

Yes, we can declare static method as synchronized. But the calling thread should acquire lock on the class that owns the method.

 

Daemon is a low priority thread which runs in the backgrouund.

When program starts JVM creates  a ThreadGroup named main. Unless specified, all  newly created threads become members of the main thread group.
ThreadGroup is initialized with default priority of 10.
ThreadGroup important methods >
•getName()
      o name of ThreadGroup.
•activeGroupCount()
      ocount of active groups in ThreadGroup.
•activeCount()
      ocount of active threads in ThreadGroup.
•list()
      olist() method has prints ThreadGroups information
•getMaxPriority()
      oMethod returns the maximum priority of ThreadGroup.
•setMaxPriority(int pri)
      oSets the maximum priority of ThreadGroup.

Thread behaviour is unpredictable because execution of Threads depends on Thread scheduler, thread scheduler may have different implementation on different platforms like windows, unix etc. Same threading program may produce different output in subsequent executions even on same platform.
To achieve we are going to create 2 threads on same Runnable Object, create for loop in run() method and start  both threads. There is no surety that which threads will complete first,  both threads will enter anonymously in for loop.

 

Thread Priority range is from 1 to 10.
Where 1 is minimum priority and 10 is maximum priority.
Thread class provides variables of final static int type for setting thread priority.
 /* The minimum priority that a thread can have. */
 publicfinalstaticintMIN_PRIORITY= 1;
 /* The default priority that is assigned to a thread. */
 publicfinalstaticintNORM_PRIORITY= 5;
 /* The maximum priority that a thread can have. */
 publicfinalstaticintMAX_PRIORITY= 10;
Thread with MAX_PRIORITY is likely to get more CPU as compared to low priority threads. But occasionally low priority thread might get more CPU. Because thread scheduler schedules thread on discretion of implementation and thread behaviour is totally unpredictable.
Thread with MIN_PRIORITY is likely to get less CPU as compared to high priority threads. But occasionally high priority thread might less CPU. Because thread scheduler schedules thread on discretion of implementation and thread behaviour is totally unpredictable.
setPriority()method is used for Changing the priority of thread.
getPriority()method returns the thread’s priority.

 

addShutdownHook method in java >
•addShutdownHook method registers a new virtual-machine shutdown hook.
•A shutdown hook is a initialized but unstarted thread.
•When JVM starts its shutdown it will start all registered shutdown hooks in some unspecified order and let them run concurrently.
When JVM (Java virtual machine)  shuts down >
•When the last non-daemon thread finishes, or
•when the System.exit is called.
Once JVM’s shutdown has begunnew shutdown hook cannot be registered neither  previously-registered hook can be de-registered. Any attempt made to do any of these operations causes an IllegalStateException.
For more detail with program read : Threads addShutdownHook method in java

Threads can be created in two ways i.e. by implementing java.lang.Runnable interface or extending java.lang.Thread class and then extending run method.

Thread has its own variables and methods, it lives and dies on the heap. But a thread of execution is an individual process that has its own call stack. Thread are lightweight process in java.
1.Thread creation by  implementingjava.lang.Runnableinterface.

We will create object of class which implements Runnable interface :

MyRunnable runnable=new MyRunnable();

Thread thread=new Thread(runnable);

2.And then create Thread object by calling constructor and passing reference of Runnable interface i.e.  runnable object :

Thread thread=new Thread(runnable);

The thread's start() method puts the thread in ready state and makes the thread eligible to run. start() method automatically calls the run () method.

Normal threads do mainstream activity, whereas daemon threads are used low priority work. Hence daemon threads are also stopped when there are no normal threads.

 

yield() is a native method it’s implementation in java 6 has been changed as compared to its implementation java @As method is native it’s implementation is provided by JVM.
In java 5, yield() method internally used to call sleep() method giving all the other threads of same or higher priority to execute before yielded thread by leaving allocated CPU for time gap of 15 millisec.
But java 6, calling yield() method gives a hint to the thread scheduler that the current thread is willing to yield its current use of a processor. The thread scheduler is free to ignore this hint. So, sometimes even after using yield() method, you may not notice any difference in output.
salient features of yield() method >
•Definition : yield() method when called on thread gives a hint to the thread scheduler that the current thread is willing to yield its current use of a processor.The thread scheduler is free to ignore this hint.
•Thread state : when yield() method is called on thread it goes from running to runnable state, not in waiting state. Thread is eligible to run but not running and could be picked by scheduler at anytime.
•Waiting time : yield() method stops thread for unpredictable time.
•Static method : yield()is a static method, hence calling Thread.yield() causes currently executing thread to yield.
•Native method : implementation of yield() method is provided by JVM.
Let’s see definition of yield() method as given in java.lang.Thread -
public static native void yield();
•synchronized block : thread need not to to acquire object lock before calling yield()method i.e. yield() method can be called from outside synchronized block.

 

Thread only when you are looking to modify run() and other methods as well. If you are simply looking to modify only the run() method implementing Runnable is the best option (Runnable interface has only one abstract method i.e. run() ).  
Differences between implementing Runnable interface and extending Thread class -
@Multiple inheritance in not allowed in java : When we implement Runnable interface we can extend another class as well, but if we extend Thread class we cannot extend any other class because java does not allow multiple inheritance. So, same work is done by implementing Runnable and extending Thread but in case of implementing Runnable we are still left with option of extending some other class. So, it’s better to implement Runnable.
@Thread safety : When we implement Runnable interface, same object is shared amongst multiple threads, but when we extend Thread class each and every thread gets associated with new object. 
@Inheritance (Implementing Runnable is lightweight operation) : When we extend Thread unnecessary all Thread class features are inherited, but when we implement Runnable interface no extra feature are inherited, as Runnable only consists only of one abstract method i.e. run() method. So, implementing Runnable is lightweight operation.
@Coding to interface : Even java recommends coding to interface. So, we must implement Runnable rather than extending thread. Also, Thread class implements Runnable interface.
@Don’t extend unless you wanna modify fundamental behaviour of class, Runnable interface has only one abstract method i.e. run()  : We must extend Thread only when you are looking to modify run() and other methods as well. If you are simply looking to modify only the run() method implementing Runnable is the best option (Runnable interface has only one abstract method i.e. run() ). We must not extend Thread class unless we're looking to modify fundamental behaviour of Thread class.
@Flexibility in code when we implement Runnable : When we extend Thread first a fall all thread features are inherited and our class becomes direct subclass of Thread , so whatever action we are doing is in Thread class. But, when we implement Runnable we create a new thread and pass runnable object as parameter,we could pass runnable object to executorService & much more. So, we have more options when we implement Runnable and our code becomes more flexible.
@ExecutorService : If we implement Runnable, we can start multiple thread created on runnable object  with ExecutorService (because we can start Runnable object with new threads), but not in the case when we extend Thread (because thread can be started only once).

 

During its execution, a thread can reside in one of the following states:
• Runnable: A thread becomes ready to run, but does not necessarily start running immediately.
• Running: The processor is actively executing the thread code.
• Waiting: A thread is in a blocked state waiting for some external processing to finish.
• Sleeping: The thread is forced to sleep.
• Blocked on I/O: Waiting for an I/O operation to complete.
• Blocked on Synchronization: Waiting to acquire a lock.
• Dead: The thread has finished its execution.

The yield() method puts currently running thread in to ready state.

  •  Method can be declared as synchronised.
  •  A block of code be sychronised.

 

Java allows threads to access shared variables. As a rule, to ensure that shared variables are consistently updated, a thread should ensure that it has exclusive use of such variables by obtaining a lock that enforces mutual exclusion for those shared variables.
If a field is declared volatile, in that case the Java memory model ensures that all threads see a consistent value for the variable.
Few small questions>
Q. Can we have volatile methods in java?
@No, volatile is only a keyword, can be used only with variables.
Q. Can we have synchronized variable in java?
@No, synchronized can be used only with methods, i.e. in method declaration.

 

We should call setDaemon(true) method on the thread object to make a thread as daemon thread.

Threads are lightweight process only if threads of same process are executing concurrently. But if threads of different processes are executing concurrently then threads are heavy weight process.

sleep() is a native method, it’s implementation is provided by JVM.
10 salient features of sleep() method >
Definition : sleep() methods causes current thread to sleep for specified number of milliseconds (i.e. time passed in sleep method as parameter). Ex- Thread.sleep(10) causes currently executing thread to sleep for 10 millisec.
Thread state : when sleep() is called on thread it goes from running to waiting state and can return to runnable state when sleep time is up.
Exception : sleep() method must catch or throw compile time exception i.e. InterruptedException.
Waiting time : sleep() method have got few options.
1.sleep(long millis) - Causes the currently executing thread to sleep for the specified number of milliseconds
public static native void sleep(long millis) throws InterruptedException;
1.sleep(long millis, int nanos) - Causes the currently executing thread to sleep for the specified number of milliseconds plus the specified number of nanoseconds.
public static native void sleep(long millis,int nanos) throws InterruptedException;
•static method : sleep()is a static method, causes the currently executing thread to sleep for the specified number of milliseconds.
•Belongs to which class :sleep() method belongs to java.lang.Thread class.
•synchronized block : thread need not to to acquire object lock before calling sleep()method i.e. sleep() method can be called from outside synchronized block.

•Should be called from synchronized block :wait() method is always called from synchronized block i.e. wait() method needs to lock object monitor before object on which it is called.  But sleep() method can be called from outside synchronized block i.e. sleep() method doesn’t need any object monitor.
•IllegalMonitorStateException : if wait() method is called without acquiring object lock than IllegalMonitorStateException is thrown at runtime, but sleep() methodnever throws such exception.
•Belongs to which class : wait() method belongs to java.lang.Object class but sleep() method belongs to java.lang.Thread class.
•Called on object or thread : wait() method is called on objects but sleep() method is called on Threads not objects.
•Thread state : when wait() method is called on object, thread that holded object’s monitor goes from running to waiting state and can return to runnable state only when notify() or notifyAll()method is called on that object. And later thread scheduler schedules that thread to go from from runnable to running state.
when sleep() is called on thread it goes from running to waiting state and can return to runnable state when sleep time is up.
•When called from synchronized block :when wait() method is called thread leaves the object lock.  But sleep()method when called from synchronized block or method thread doesn’t leaves object lock.

In Java programming, each object has a lock. A thread can acquire the lock for an object by using the synchronized keyword.
The synchronized keyword can be applied in a method level (coarse grained lock) or block level of code (fine grained lock).