➤ How to Code a Game
➤ Array Programs in Java
➤ Java Inline Thread Creation
➤ Java Custom Exception
➤ Hibernate vs JDBC
➤ Object Relational Mapping
➤ Check Oracle DB Size
➤ Check Oracle DB Version
➤ Generation of Computers
➤ XML Pros & Cons
➤ Git Analytics & Its Uses
➤ Top Skills for Cloud Professional
➤ How to Hire Best Candidates
➤ Scrum Master Roles & Work
➤ CyberSecurity in Python
➤ Protect from Cyber-Attack
➤ Solve App Development Challenges
➤ Top Chrome Extensions for Twitch Users
➤ Mistakes That Can Ruin Your Test Metric Program
Java Multithreading Interview Questions | In Java, multithreading is one of the most important areas to ask questions in the interview therefore we have prepared more questions and answers on Java multithreading.
Table of Contents
- Java Multithreading Introduction Interview Questions
- Defining Threads in Java – Multithreading
- Thread Priority, yield(), join() & sleep() Questions
- Java Synchronization Interview Question
- Inter-Thread Communication, Deadlock, Daemon Thread Interview Questions
Java Multithreading Introduction Interview Questions
1. What is Multi-Tasking?
The process of executing multiple tasks at a time concurrently is called multitasking. Multithreading is used to obtain multitasking. It consumes less memory and gives an efficient performance.
2. What are the different ways of executing tasks?
The three different flows of executing tasks:-
- Sequential flow of execution:- Two tasks are executed one after one. It means the second task execution is started only after the first task execution is fully completed.
- Parallel flow of execution:- Two tasks are executed at a time without depending on each other. It means at the same point of time two tasks can be in running mode.
- Concurrent flow of execution:- Two tasks are executed simultaneously (at a time concurrently). It means the second task will be run only when the first task execution is paused. Similarly, first task execution is resumed when the second task is paused.
3. What are the different types of multitasking?
There are two types of multitasking:-
- Process based multitasking
- Thread based multitasking
4. What is process-based multitasking?
Executing several tasks simultaneously where each task is a separate independent process (or program) is called process-based multitasking.
Example:- Assume while typing the Java program in a text editor, you are also listening to music, and downloading a file. Here coding in text editor, music system player, and downloading a file will be executed simultaneously but they are independent of each other. Process-based multitasking is best suitable at the OS (operating system) level but not at the programmatic level.
5. What is thread-based multitasking?
Executing several tasks simultaneously where each task is a separate independent part of the same program is called thread-based multitasking. It is best suitable at the programmatic level.
6. What is Thread?
Thread is an independent sequence flow of execution. It executes the method in sequence one after one. Each thread runs in a different stack frame. A process may contain multiple threads. Threads share the process resources, but still, they execute independently.
7. What is multithreading?
Multithreading is a process of creating multiple threads for executing multiple independent tasks concurrently to complete their execution in less time by using CPU ideal time effectively.
8. What is the main advantage of multithreading?
The main advantage of multithreading is to increase the performance of the system by reducing response time. Its other advantages are:
- Multithreading provides better utilization of cache memory as threads share the common memory resources.
- Multithreading reduces the number of the required server as one server can execute multiple threads at a time.
- Multithreading allows an application/program to be always reactive for input, even already running with some background tasks
- Multithreading allows the faster execution of tasks, as threads execute independently.
9. What is the difference between multitasking and multithreading?
Multitasking | Multithreading |
---|---|
The process of executing multiple independent main tasks at a time concurrently is called multitasking. | The process of executing multiple independent sub-tasks in one main task at a time is called multithreading. |
Each task is executed in a separate process. | All tasks are executed in a single process. |
Multitasking is heavyweight because switching between contexts is slow. Here each task is executed in a separate process which is created at a different address. | Multithreading is lightweight because switching between contexts is fast. Here all threads are created in a single process means threads are created in the same address. |
Multitasking exists at the OS level. Example:- Windows, Linux, Mac. | Multithreading exists at the process level. Example:- JVM. |
10. Is Java by default a multithreaded programming language?
Yes, by default Java is a multithreaded programming language. JVM creates a “main” thread group that creates a “main” thread. The “main” thread is responsible for calling the main() method. Not only the main thread but JVM also creates many daemon threads that run in the background to provide services to the non-daemon threads. See more:- Daemon thread in Java
11. What is a thread scheduler?
Thread Scheduler is part of JVM and it is responsible for scheduling thread execution. If multiple threads are waiting to get the chance of execution then in which order threads should be executed is decided by the thread scheduler.
12. What is the Job of Thread Scheduler?
The main task of the thread scheduler is:- Scheduling the thread execution.
13. What is the meaning of single-thread model and multi-thread model application?
If the entire application is executed by a single thread itself then it is called a single thread model application. But if the application is executed by multiple threads then it is called a multi-thread model application.
14. What is the problem with a single thread of execution?
In a single thread flow of execution, if one task execution is paused, this paused time will not be used for executing other tasks. Here execution time will be wasted. Due to this waste of paused time, program execution takes more time. Using multithreading one task paused time will be allocated to execute another task so that program execution will be fast.
15. When should we create multiple threads to execute different tasks?
To complete independent multiple tasks execution in less time we should create multiple threads. In multithreading-based programming, CPU ideal time is utilized effectively.
16. What is the use of the main thread and garbage collector thread?
The main thread is used for executing Java methods logic by providing separate memory blocks in it. This memory block is technically called a stack frame. As many methods and constructors invoke those many new stack frames are created. Once the current method and constructor logic are executed, the stack frame is destroyed.
The garbage collector is used for destroying unreferenced objects from the heap area, and freeing this memory, and returning it to the JVM. So, JVM will use this free memory for creating new objects.
17. What is context switching?
In Context switching the state of the process (or thread) is stored so that it can be restored and execution can be resumed from the same point later. Context switching enables multiple processes to share the same CPU.
18. Does each thread have its stack in multithreaded programming?
Yes, in multithreaded programming every thread maintains its own or separate stack area in memory due to which every thread is independent of each other.
Defining Threads in Java – Multithreading
1. What are the different ways to define a thread in Java?
We can define a thread in the following 2 ways,
- By extending Thread class.
- By implementing Runnable interface.
Defining a thread in Java by extending from Thread class,
// defining a thread extending from Thread class
class MyThread extends Thread {
// override run() method
@Override
public void run() {
// code
}
}
// Testing
public class ThreadDemo {
public static void main(String[] args) {
// thread instantiation
MyThread t = new MyThread();
t.start(); // child thread start
}
}
Defining a thread by implementing the Runnable interface,
// defining a thread by implementing Runnable interface
class MyThread implements Runnable {
// implement run() method
@Override
public void run() {
// code
}
}
// Testing
public class ThreadDemo {
public static void main(String[] args) {
MyThread mt = new MyThread();
MyThread t = new MyThread(mt);
t.start(); // child thread start
}
}
2. Among these two ways of defining a thread which is better and why?
Defining a thread by implementing the Runnable interface is better and recommended to use.
In the first approach (by extending from Thread class) our class already extends from the Thread class therefore there is no chance of extending it from any other class. In this way, we will miss inheritance benefits.
In the 2nd way (by implementing Runnable interface) our class can extend from any class. And due to this reason, we will have inheritance benefits. Therefore in these two ways, the 2nd way i.e. “implementing from Runnable interface” is recommended. The 1st way also gives performance issues.
3. If we want to start a thread then which method must be called start() or run() method?
The start() method. If we call the run() method then it will be executed as a normal method called, and a new thread will not be created.
4. Why do we need to call the start() method for starting a new thread?
Thread class start() method is responsible for,
- Register the thread with thread scheduler.
- Perform all other mandatory activities.
- Invoke run() method.
Hence, without executing the thread class start() method there is no chance of starting a new thread in Java.
5. When we call the start() method on a Thread object, will thread execution start immediately?
No, the start() method has to perform some important activities like- register the thread, perform all other mandatory activities. After completing these operations it will invoke the run() method, and then thread execution will be started.
6. What is the difference between t.start() and t.run()?*
MyThread t = new MyThread();
t.start();
t.run();
In the case of the t.start() method, a separate thread will be created which will be responsible for the execution of the run() method. But in the case of the t.run() method, it will be a normal method call. A new thread will not be created, and the run() method will be executed by the main thread itself.
7. Can we overload the run() method?
Yes, overloading of the run() method is possible but the Thread class start() method always invokes the run() method with no argument. To execute another overloaded form of the run() method we have to call it explicitly like a normal method call.
class MyThread extends Thread {
// start() method always call run()
@Override
public void run() {
// call other run(-) method from here
run(7.5);
}
public void run(double n) {
// code
}
}
Note:- Overloading of the main() method is also possible but the main thread always calls:- “public static void main(String[] args)” method. Other overloaded forms of main() will be treated like normal methods, and to execute them we have to call them explicitly.
8. What happens if we don’t override the run() method (when the thread is defined by extending from the Thread class)?
class MyThread extends Thread { }
public class ThreadDemo {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
}
}
Since the run() method is not available in the child class (MyThread) therefore it will be executed from the parent class (Thread class). The run() method of the Thread class has an empty implementation. Therefore the program will run successfully but this child thread won’t give any output.
9. What happens if we override the start() method?*
class MyThread extends Thread {
@Override
public void start() {
// code
}
@Override
public void run() {
// code
}
}
Since we are overriding the start() method in the MyThread class, therefore the start() method of the Thread class will not get a chance to execute. In this case, the start() method of MyThread will be executed like a normal method call. A new thread will not be created. Complete execution will be done by only the main thread, therefore output will be fixed.
10. After Starting the Thread if we are restarting the same thread then what happens?*
class MyThread extends Thread {
@Override
public void run() {
// code
}
}
public class ThreadDemo {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
// some code
t.start();
}
}
After starting a thread if we are trying to restart the same thread then we will get the runtime exception:-java.lang.IllegalThreadStateException. Hence we can’t start a thread more than once.
11. Explain the life cycle phases of a thread.
- NEW:- Thread has been created but not yet started. The thread will be started after the start() method call.
- RUNNABLE:- Thread is running, and currently executing.
- TIMED_WAITING: The thread was running, and now it is waiting for a certain fixed amount of time. After that time period, the thread scheduler decides which thread will get a chance to execute.
- WAITING: The thread was running, and now it is waiting for its turn. The thread scheduler decides which thread will get a chance to execute.
- BLOCKED: The thread got blocked for some reason.
- TERMINATED:- Thread execution completed.
12. How can we get the state of a thread?
We can get the state of a thread by using the getState() method.
MyThread mt = new MyThread();
System.out.println(mt.getState()); // NEW
mt.start();
System.out.println(mt.getState()); // RUNNABLE
13. How can we find whether a given thread is a live thread or not?
We find whether a given thread is a live thread or not by using isAlive() method.
class MyThread extends Thread {}
public class Test {
public static void main(String[] args) throws Exception {
MyThread mt = new MyThread();
System.out.println(mt.isAlive()); // false
mt.start();
System.out.println(mt.isAlive()); // true
Thread.sleep(2000);
System.out.println(mt.isAlive()); // false
}
}
14. How can we get the name of a thread?
Using getName() method. The getName() method defined in the Thread class returns the name of the thread.
MyThread mt = new MyThread();
System.out.println(mt.getName()); // Thread-0
15. How can we set the name of a thread?
Using setName() method. The setName(String str) method defined in the Thread class sets the name of the given thread.
MyThread mt1 = new MyThread();
mt1.setName("KnowProgram");
System.out.println(mt1.getName()); // KnowProgram
The thread name can be changed even after starting the thread, JVM won’t give any error. The main thread is already started in the below program (question 16), but we are changing its name by getting its reference.
16. How can we get the currently running thread reference?
Thread.currentThread() method. The currentThread() method of the Thread class is a static method that returns a reference to the currently running thread.
public class Test {
public static void main(String[] args) {
Thread t = Thread.currentThread();
System.out.println(t.getName()); // main
t.setName("KnowProgram");
System.out.println(t.getName()); // KnowProgram
}
}
17. What is the default name of the child thread?
By default, JVM assigns the name of the child thread as thread-0, thread-1, thread-2, and so on.
18. Can we create multiple threads with the same name?
Yes, we can create multiple threads with the same name.
MyThread mt = new MyThread();
mt.setName("KP");
mt.start();
System.out.println(mt.getName()); // KP
MyThread mt1 = new MyThread();
mt1.setName("KP");
mt1.start();
System.out.println(mt.getName()); // KP
Thread Priority, yield(), join() & sleep() Questions
Thread Priority
Q1) What is thread priority?
Every thread in JVM is created with a priority value which is called thread priority.
Q2) What is the default priority of every new thread?
The default priority of the new thread is inherited from the parent thread. For example:- the default value of the main thread is 5, if a new thread is created by the main thread then the newly created thread having priority = 5.
Q3) Why do most of the threads have default priority 5?
Most of the threads are created by the main thread. The default priority of the main thread is 5, therefore by default the priority of the child thread will be 5.
Q4) What is the range of thread priority?
The valid range of thread priority is 1 to 10.
Q5) How can we get & set the priority of a thread?
Using getPriority() and getPriority(int p) methods. While calling the getPriority() method the passed value must belong to 1 to 10.
Q6) What will happen if we set thread priority to 20?
We will get Runtime error:- java.lang.IllegalArgumentException
Q7) If two threads have different priority then which thread will execute first?
The thread having high priority will get a chance first to execute.
Q8) If two threads have the same priority, which thread will execute first?
If two threads are having the same priority then their execution order will be decided by the thread scheduler, we can’t expect anything.
Q9) When a new thread is born, how can we start execution immediately compared to other threads?
Assign higher priority compared to parent and sibling threads. The thread having high priority will get the first chance to execute.
Q9.1) What will happen if we set thread priority after starting the thread?
Setting the priority of a thread after it has started will immediately change the thread’s priority. The Java Thread class provides the setPriority method to adjust a thread’s priority at any point during its lifecycle.
public class Test {
public static void main(String[] args) throws InterruptedException {
System.out.println("Test.main() - start");
Thread t = new Thread(() -> {
System.out.println("Child thread");
Thread currentThread = Thread.currentThread();
System.out.println("Priority: " + currentThread.getPriority());
});
t.start();
t.setPriority(7);
System.out.println("Test.main() - end");
}
}
Preventing thread from Execution (yield(), join() and sleep() Methods)
Q10) What are the different ways to pause thread Execution?***
Different ways to prevent or stop a thread execution temporarily (not permanently) are:-
- sleep() method
- join() method
- yield() method
Q11) When should we use the sleep() method?
If a thread doesn’t want to perform any operation for a particular amount of time then we can use the sleep() method.
public class Test {
public static void main(String[] args) throws InterruptedException {
System.out.println("Test.main() - start");
Thread t = new Thread(() -> {
System.out.println("Child thread - start");
try {
Thread.sleep(1000); // 1 sec
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Child thread - end");
});
t.start();
Thread.sleep(2000); // 2 sec
System.out.println("Test.main() - end");
}
}
Output:-
Test.main() – start
Child thread – start
Child thread – end
Test.main() – end
Q12) When should we use the join() method?
If a thread wants to wait until the completion of some other thread then we should go for the join() method. It is also used for timed waiting.
public class Test {
public static void main(String[] args) throws InterruptedException {
System.out.println("Test.main() - start");
Thread t = new Thread(() -> {
System.out.println("Child thread - start");
try {
Thread.sleep(2000); // 2 sec
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Child thread - end");
});
t.start();
// main thread will wait for the completion of thread t
t.join();
System.out.println("Test.main() - end");
}
}
Output:-
Test.main() – start
Child thread – start
Child thread – end
Test.main() – end
Q13) What is the purpose of the yield() method?***
The yield() method pauses the currently executing thread to give the chance for waiting threads of the same priority or higher priority.
- If there are no waiting threads or all waiting threads have low priority then the same thread can continue its execution.
- If multiple threads are waiting with the same priority then which waiting thread will get a chance:- we can’t expect, it depends on the thread scheduler.
- The thread which is yielding, when it will get the chance back it also depends on the thread scheduler and we can’t expect exactly.
The yield() method hints to the thread scheduler that the current thread is willing to pause its execution to let other threads of equal or higher priority have a go. However, it’s just a suggestion to the scheduler, which can decide based on its own rules and logic. Threads with lower priority won’t get a chance to run because of a yield() call. It’s like a courteous way of saying, “I can wait if there’s someone else ready to go.”
public class Test {
public static void main(String[] args) throws InterruptedException {
System.out.println("Test.main() - start");
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 1 - iteration " + i);
Thread.yield(); // give chance for thread-2 execution
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 2 - iteration " + i);
Thread.yield(); // give chance for thread-1 execution
}
});
t1.start();
t2.start();
// main thread will wait till the completion of t1 & t2 threads
t1.join();
t2.join();
System.out.println("Test.main() - end");
}
}
Sample Output:-
Test.main() – start
Thread 1 – iteration 0
Thread 1 – iteration 1
Thread 2 – iteration 0
Thread 1 – iteration 2
Thread 2 – iteration 1
Thread 1 – iteration 3
Thread 2 – iteration 2
Thread 1 – iteration 4
Thread 2 – iteration 3
Thread 2 – iteration 4
Test.main() – end
Q14) How can a thread interrupt another thread?
By using the interrupt() method a thread can interrupt another thread. The thread will be interrupted only if it enters into the waiting or sleeping state, otherwise there will not be any impact of interrupt() method call.
public class Test {
public static void main(String[] args) throws InterruptedException {
System.out.println("Test.main() - start");
Thread t = new Thread(() -> {
try {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 1 - iteration " + i);
Thread.sleep(1000); // 1 sec
}
} catch (InterruptedException e) {
System.out.println("Thread was interrupted.");
}
});
t.start();
Thread.sleep(2500);
// interrupt
t.interrupt();
System.out.println("Test.main() - end");
}
}
Sample Output:-
Test.main() – start
Thread 1 – iteration 0
Thread 1 – iteration 1
Thread 1 – iteration 2
Test.main() – end
Thread was interrupted.
Q15) What happens after calling the interrupt() method if the target thread is not in a waiting or sleeping state?
When we call the interrupt() method and the target thread is not in a waiting or sleeping state then there will be no impact of interrupt call immediately. The interrupt calls will wait till the target thread enters into the waiting or sleeping state.
- If the target thread enters into the waiting or sleeping state:- Then the interrupt call will immediately interrupt the target thread, and InterruptedException will be raised. Interrupt calls will not be wasted.
- If the target thread never entered into the waiting or sleeping state in its lifetime:- Then the interrupt call will be wasted and no impact on the interrupt() call.
Q16) If the interrupt() method is called on the child thread by the main thread, then will the main thread wait till the child thread gets interrupted?
public class Test {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
t.interrupt();
// other work
}
}
No, the main thread will not wait, it will continue its execution. Interrupting the thread is the task of JVM. This job will be done by JVM, the main thread will not wait, it will continue its operation.
Q17) Difference between yield() and join() method?***
If a thread wants to pause its execution to give the chance for remaining threads of the same priority or higher priority then the yield() method is used. But if a thread wants to wait until the completion of some other thread then the join() method is used.
public static native void yield()
public final void join() throws InterruptedException
public final void join(long ms) throws InterruptedException
public final void join(long ms, int ns) throws InterruptedException
The yield() method doesn’t contain any overload form, doesn’t throw Exception whereas the join() method contains three overloaded forms, and all of them throw InterruptedException. The yield() method is native, and static whereas join() method is final, instance nature defined in Java (not native).
Q18) What is the difference between yield() and sleep() method?
The yield() method is used If a thread wants to pause its execution to give the chance for remaining threads of the same priority or higher priority. Whereas the sleep() method is used If a thread doesn’t want to perform any operation for a particular amount of time.
public static native void yield()
public static native void sleep(long ms) throws InterruptedException
public static void sleep(long ms, int ns) throws InterruptedException
Q19) What is the difference between join(), join(1000), and sleep(1000)?
- If the join() method is called on the child thread by the main thread then the main thread will wait till execution completion of the child thread.
- But if the join(1000) method is called on the child thread by the main thread then the main thread will wait a maximum 1000 milliseconds. If within 1000 ms child thread execution is not completed then the main thread will come out of the waiting state and try to start its own execution.
- When sleep(1000) is called then the compulsory thread has to wait 1000 ms after that it will try to start its own execution.
Q20) Comparison table for yield(), join() and sleep() Method of thread class?
Properties | yield() | join() | sleep() |
---|---|---|---|
Purpose (When should we use it?) | We should use the yield() method if a thread wants to pause its execution to give the chance for remaining threads of the same priority or higher priority. | If a thread wants to wait until the completion of some other thread then we should go for the join() method. | We should use the sleep() method If a thread doesn’t want to perform any operation for a particular amount of time. |
Is it overloaded? | No | Yes | Yes |
Is it final? | No | Yes | No |
Is it throwing an InterruptedException? | No | Yes | Yes |
Is it Native? | Yes | No | sleep(long ms) => native; sleep(long ms, int ns) => non-native |
Is it static? | Yes | No | Yes |
public static native void yield()
public final void join() throws InterruptedException
public final void join(long ms) throws InterruptedException
public final void join(long ms, int ns) throws InterruptedException
public static native void sleep(long ms) throws InterruptedException
public static void sleep(long ms, int ns) throws InterruptedException
Java Synchronization Interview Question
Q1) When should we develop synchronization, and why?
If multiple threads are operating simultaneously on the same Java object/class then there will be a chance to get data inconsistency problems. This problem is also known as the “race condition”. To overcome this problem we should use the synchronization concept.
Q2) Why is the object data modified inconsistently from multiple threads?
Threads are executing concurrently. In this case, when the first thread execution is paused, the second thread modifies object data in the middle of the first thread execution, after resuming the first thread it uses the second thread’s modified values, but not its actual values. This is called a data inconsistent modification problem and it leads to wrong results.
Q3) Explain different application areas where synchronization is used.
Bank applications, every web application, ticket booking system, and e.t.c.
Q4) How can we develop synchronization in Java?
In Java synchronization is implemented by using the synchronized keyword. We can apply the synchronized keyword either to methods and/or to local blocks. So, in Java synchronization is developed:-
- By using synchronized methods.
- By using synchronized blocks.
Q5) What is the synchronized keyword and where can we apply it?
The synchronized is a modifier applicable for methods and blocks but not for class, objects, and variables.
Q6) What is the advantage of the synchronized keyword?
We can resolve data inconsistency problems.
If a method/block is declared as synchronized then at a time only one thread is allowed to execute that method/block on the given object, other threads have to wait till the completion of the allowed thread. Therefore, the data inconsistency problem will be solved.
Q7) Disadvantages of synchronized keywords?
It increases the waiting time of threads and gives performance issues. Threads will be executed one by one which increases the waiting time of the thread.
To solve these problems instead of using the synchronized keyword we can use java.util.concurrent package.
Q8) What is race condition?*
If multiple threads are operating simultaneously on the same Java object then there will be a chance of data inconsistency problems. This data inconsistency problem in Java is also known as a race condition. To resolve race conditions we should use a synchronized keyword/modifier.
Q9) What is an object-level lock and when is it required?
Every object in Java has a unique lock that is nothing but an object-level lock. Whenever a thread wants to execute an instance synchronized method or block then it needs to acquire the object level lock.
public synchronized void m1() {
// code
}
Q10) What is class level lock and when is it required?
Every class in Java has a unique lock which is nothing but a class-level lock. Whenever a thread wants to execute a static synchronized block or method then the thread needs to acquire the class-level lock.
public static synchronized void m2() {
// code
}
Q11) Difference between the class-level lock and object-level lock?
If a thread wants to execute a static synchronized method/block then the class-level lock is required. Whereas if a thread wants to execute an instance synchronized method/block then object level lock is required.
Q12) What will happen when the synchronized method is called?
When a synchronized method is called, the object will be locked while executing the method.
Q13) What is the meaning of an object being locked and unlocked?
Locking an object means marking the current object is not allowed to another thread for calling synchronized method/block. Unlocking an object means marking this object as available to other threads to access its functions.
Q14) When a thread is called a monitor?
Monitor means a thread that holds the lock of an object is called monitor. Note that an object has only one monitor which means an object can be locked by only one thread at a time.
Q15) While a thread is executing a synchronized method on the given object, are the other threads allowed to execute any other synchronized methods simultaneously on the same object?
No, once an object is locked by a thread then other threads can’t execute any synchronized method/block simultaneously on that object.
Q16) When an object is locked can another thread use it to execute a non-synchronized method?
Yes, because the lock/unlock concept is applicable only for the synchronized method/block but not for the non-synchronized method.
Q17) If threads are using different objects, will the synchronized method execution be concurrent or sequential?
Since objects are different therefore the synchronization concept is not applicable. Hence execution will be concurrent i.e. they will execute simultaneously not one by one.
Q18) What is the difference between declaring the instance method and the static method as synchronized?
If we declare an instance method as synchronized its current object is locked so that in this method instance variables of this object are modified sequentially by multiple threads. If we declare a static method as synchronized then its class’s java.lang.Object is locked so that in this method static variables are modified sequentially by multiple threads.
In a static method by using a synchronized block, we can only lock an argument object but not the current object because “this” keyword doesn’t exist in the static method.
Q19) What is a synchronized block?
A block surrounded by a synchronized keyword is called a synchronized block.
class Display {
public void wish(String name) {
// synchronized block
synchronized(this) {
// code
}
}
}
Q20) What is the need for a synchronized block?
Assume we have an m1() method with 10k lines of code (linking method, internally method is calling other methods) among these lines only 10 lines require synchronization. In that case, if we declare the m1() method as the synchronized method then it is the worst kind of practice in Java programming. It will increase the waiting time of the thread and give very poor performance.
Therefore if only a few lines of code are required for synchronization then it is never recommended to declare the whole method as synchronized rather we should use the synchronized block for those lines of code.
Q21) What is the difference between synchronized methods and blocks?
If a method is declared as synchronized, that method’s complete logic is executed in sequence from multiple threads by using the same object. For different objects, it is executed concurrently from multiple threads. If we declare a block as synchronized, only the statements written inside that block are executed sequentially but not the complete method logic.
Using synchronized methods we can only lock the current object of the method. Using a synchronized block we can lock the current object, argument object of the method, or any class.
Q22) Can we define multiple synchronized blocks in a method?
Yes, we can define multiple synchronized blocks in a method.
Q23) What is the advantage of the synchronized block over the synchronized method?
Waiting time of thread decreased and performance improved.
Q24) How to declare a synchronized block to get the lock of the current object?
synchronized(this)
synchronized(this) {
// code
}
Q25) How to declare a synchronized block to get the class level lock?
synchronized(ClassName.class)
synchronized(Employee.class) {
// code
}
Q26) Is it possible, a thread can acquire multiple locks simultaneously?
Yes, a thread can acquire multiple locks simultaneously.
class X {
// x.m1() called
public synchronized void m1() { // "x" locked
Y y = new Y();
synchronized(y) { // "y" locked
Z z = new Z();
synchronized(z) { // "z" locked
// currently thread holds
// "x", "y", and "z" objects lock
}
}
}
}
We want to call the m1() method. To call the m1() method,
X x = new X();
x.m1();
When a thread wants to execute the synchronized method, then the compulsory thread has to acquire the lock of the current object. Therefore to execute the m1() method thread has to acquire the “x” object lock.
To enter into the 1st synchronized block “y” object lock is required. Similarly, to enter into the 2nd synchronized block “z” object lock is required. Inside the 2nd synchronized block thread contains the lock of “x”, “y”, and “z” objects.
Q27) By how many threads an object can be locked at a time?
At a time, only one thread can get the lock of an object.
Q28) When should we develop multiple synchronized blocks instead of declaring complete methods as synchronized?
In the below two cases, we develop multiple synchronized blocks,
- For executing parts of method logic sequentially for doing object modification.
- For executing some part of method logic by locking current object and other part of method by locking argument object.
Q29) What is a synchronized statement?
As per Java specification, there is no such type of terminology but the interview person uses this synchronized statement. According to them:- the statement present in a synchronized method or synchronized block is called a synchronized statement.
Q30) What is the meaning of thread-safe & non-thread-safe objects?
If an object is not accessible for multiple threads concurrently for modifying values, or one thread modification on the object is not affected to another thread, then that object is called a thread-safe object.
If an object is accessible for multiple threads concurrently for modifying values, and modification by one thread on this object is also available to other threads then that object is called a non-thread-safe object.
Q31) How can we develop thread-safe objects?
We can develop thread-safe objects in two ways,
- By declaring all mutator methods of this object as synchronized. Or,
- By creating objects as immutable.
Inter-Thread Communication, Deadlock, Daemon Thread Interview Questions
Inter-Thread Communication
Q1) What is inter-thread communication?
The process of executing multiple threads alternatively in sequence with communication for modifying and reading data from the same object is called inter-thread communication. We develop this concept when two different dependent tasks need to be executed continuously in sequence by two different threads on the same object.
Q2) How can two threads communicate with each other?***
Two threads can communicate with each other by using wait(), notify(), and notifyAll() methods.
Q3) The wait(), notify(), and notifyAll() methods are given in which class?
These methods are given in java.lang.Object class.
Q4) Why wait(), notify(), and notifyAll() methods are defined in java.lang.Object class but not in Thread class or Runnable interface?***
Thread can call wait(), notify(), and notifyAll() methods on any Java object. To call a method on any object the method must be present in that class or parent class. Since java.lang.Object is the superclass of all Java classes therefore they are defined in the java.lang.Object class.
Q5) The wait(), notify(), and notifyAll() methods must be called from?
We can call these methods only from the synchronized area (block/method) else IllegalMonitorStateException will be raised at runtime.
public class Test {
private static final Object LOCK = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
synchronized (LOCK) {
try {
System.out.println("Thread 1: waiting for the lock.");
LOCK.wait();
System.out.println("Thread 1: Notified and resumed execution.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
synchronized (LOCK) {
try {
Thread.sleep(2000);
System.out.println("Thread 2: Work done. Notifying thread 1.");
LOCK.notify(); // Thread 2 notifies thread 1
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
}
}
Thread 1: waiting for the lock.
Thread 2: Work done. Notifying thread 1.
Thread 1: Notified and resumed execution.
Q6) What happens when a thread calls the wait() method on any object?
When a thread calls the wait() method on an object then immediately thread releases the lock of that particular object and enters into the waiting state.
Note that only the lock of that particular object is released, it won’t release the lock of other objects. Suppose at the time of calling wait() method, thread contains the lock of 10 objects then the thread will release lock for only 1 object on which wait() method was called, it won’t release lock for the remaining 9 objects.
Q7) What happens when a thread calls notify() method on any object?
When a thread calls notify() method on any object then it releases the lock of the object but may not immediately. And it also gives notification to the waiting thread.
For example, the x.wait() method was called by one thread. This thread will release the lock and went into the waiting state to get the notification.
After calculation, x.notify() was called by another thread. Therefore this thread will release the lock of the object and give notification to the waiting thread.
Q8) What will happen if we do not call notify() or notifyAll() methods on the waiting thread?
That thread will be in the waiting state forever.
Q9) What are the methods due to them a thread can release the lock?
The wait(), notify(), and notifyAll() are only methods where the thread releases the lock.
Q10) What is the difference between notify() and notifyAll() method?
We can use notify() method to give the notification for only one waiting thread. If multiple threads are waiting to get the notification then only one thread will be notified, the remaining threads have to wait for further notifications. We can’t expect which thread will be notified, it completely depends upon the JVM and Thread Scheduler. We can use notifyAll() to give the notification for all waiting threads on a particular object.
Q11) What is the exception we must handle while calling the wait() method?
InterruptedException
Q12) What is the difference between sleep(100), join(100), and wait(100) method calls?
- The sleep(100) blocks thread execution independent of other threads for 100 milliseconds.
- The join(100) blocks thread execution by depending on whether another thread execution is completed or till 100 milliseconds completed, whichever comes first thread resumes its execution immediately.
- The wait(100) blocks thread execution by depending on either other thread till it is called notify() or till 100 milliseconds are completed, whichever comes first thread resumes its execution immediately.
Q13) What are the rules for using wait(), notify(), and notifyAll() methods?
- The wait() method throws an InterruptedException, which is a checked exception. Therefore it must be handled whenever wait() is called.
- The wait(), notify(), and notifyAll() method must be called only in synchronized method/block else we will get an IllegalMonitorStateException.
- If we call the no-arg wait() method, later from another thread then we must call notify()/notifyAll() method else this thread execution is in WAITING state forever.
- If we want to resume thread after some time even though notify() method is not called we must use wait(long time) or wait(long ms, int ns) method.
Deadlock and Starvation
Q1) What is a deadlock in Java?
If two threads are waiting for each other to complete their execution then such type of infinite waiting situation is called deadlock. See more:- Deadlock in Java with example.
Q2) What is the keyword that causes deadlock?
The synchronized keyword. Deadlock occurs only because of the synchronized keyword.
If we don’t use the synchronized keyword then we never encounter the deadlock situation. In some cases, the program may reach into the infinite waiting state but it is not a deadlock situation. See more:- How to detect deadlock in Java.
Q3) How to avoid a deadlock situation?
We can avoid deadlock situation by using follows:-
- Avoid nested locks:- Avoid nested locks as much as possible.
- Avoid unnecessary locks:- Use locks only on necessary objects.
- Use thread join:- Use join(long ms) or join(long ms, int ns) to wait for a certain period of time.
- Use java.util.concurrent package.
Q4) Write a Java program to demonstrate deadlock in Java.
We discussed this program in detail here:- Deadlock in Java
Q5) What is the difference between deadlock and starvation?
Long time waiting of two threads for each other where waiting never ends is called deadlock whereas the long time waiting of a thread where waiting may end at a certain point is called starvation. See more:- Starvation in Java
Q7) What is livelock?
A thread often acts in response to the action of another thread. If the other thread’s action is also a response to the action of another thread, then livelock may result. As with deadlock, livelocked threads are unable to make further progress.
Daemon Thread
Q1) How many types of threads can be created in JVM?
We can create two types of threads:- non-daemon thread and daemon thread.
Q2) What is a daemon thread in Java?
A thread that is running in the background based on a schedule to provide services to non-daemon threads is called a daemon thread. Daemon threads are also called service threads. Examples of daemon threads in Java are:- garbage collectors, attach listeners, signal dispatchers, and e.t.c. See more:- Daemon Thread in Java
Q3) What is a non-daemon thread?
A thread that executes the main logic of the program/project is called a non-daemon thread. Example of non-daemon thread:- main thread.
Q4) Why are most of the threads created as non-daemon threads?
The daemon/non-daemon nature of thread is inherited from the parent thread. If the parent thread is a daemon thread then the child thread also will be a daemon thread and similarly, if the parent thread is a non-daemon thread then the child thread will be a non-daemon thread.
Most of the threads are created by the main thread. Since the main thread is a non-daemon thread, therefore, all the child threads created by the main method are also non-daemon threads.
Q5) How can we find whether the given thread is a daemon or not?
We can check the daemon nature of the thread by using the isDaemon() method of the Thread class.
Q6) Which method can be used to create a daemon thread?
We can change the daemon nature of the thread by using the setDaemon() method of the Thread class.
Q7) What is the rule in calling the setDaemon() method?
The setDaemon() method must be called before starting of the thread else we will get java.lang.IllegalThreadStateException.
Q8) Is it possible to change the daemon property after starting a thread?
No, because the setDaemon() method must be called before starting the thread.
Q9) Is it possible to change the daemon nature of the main thread?
No, there is no way to change the daemon nature of the main thread because the main thread is already started by the JVM at the very beginning. Therefore it is impossible to change the daemon nature of the main thread.
Q10) When is the daemon thread execution completed?
The main purpose of the daemon thread is to provide services to the non-daemon threads. If there is no non-daemon thread left in the program then daemon threads will be terminated.
Q11) If we create a custom thread as a daemon can we guarantee its full execution?
No, once the last non-daemon thread in the program terminates then all daemon threads of the program will be terminated immediately. Hence, full execution of the daemon thread is not guaranteed.
Q12) JVM waits for which thread to complete:- non-daemon or daemon?
JVM waits only for non-daemon threads to complete.
Q13) What is a green thread?***
The thread that is managed completely by the JVM without taking underlying operating system support is called the green thread. Most of the operating systems won’t provide support for the green thread model. Very few operating systems like Sun Solaris provide support for the green thread model.
If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or do you find anything incorrect? Let us know in the comments. Thank you!