Top 80 Thread- Java Interview Questions and Answers (Part 2)
Join the DZone community and get the full member experience.
Join For FreePART 1 > THREADS - Top 80 interview questions and answers (detailed explanation with programs)
Question 61.
class MyRunnable implements Runnable{ public void run(){ for(int i=0;i<3;i++){ System.out.println("i="+i+" ,ThreadName="+Thread.currentThread().getName()); } } } public class MyClass { public static void main(String...args){ MyRunnable runnable=new MyRunnable(); System.out.println("start main() method"); Thread thread1=new Thread(runnable); Thread thread2=new Thread(runnable); thread1.start(); thread2.start(); System.out.println("end main() method"); } }
Answer.
Thread behaviour is unpredictable because execution of Threads depends on Thread scheduler,
start main() method will be the printed first, but after that we cannot guarantee the order of thread1, thread2 and main thread they might run simultaneously or sequentially, so order of end main() method will not be guaranteed.
/*OUTPUT
start main() method
end main() method
i=0 ,ThreadName=Thread-0
i=0 ,ThreadName=Thread-1
i=1 ,ThreadName=Thread-0
i=2 ,ThreadName=Thread-0
i=1 ,ThreadName=Thread-1
i=2 ,ThreadName=Thread-1
*/
Question 62.
class MyRunnable implements Runnable{ public void run(){ for(int i=0;i<3;i++){ System.out.println("i="+i+" ,ThreadName="+Thread.currentThread().getName()); } } } public class MyClass { public static void main(String...args) throws InterruptedException{ System.out.println("In main() method"); MyRunnable runnable=new MyRunnable(); Thread thread1=new Thread(runnable); Thread thread2=new Thread(runnable); thread1.start(); thread1.join(); thread2.start(); thread2.join(); System.out.println("end main() method"); } }
Answer. We 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 join() method waited for this thread to die.
/*OUTPUT
In main() method
i=0 ,ThreadName=Thread-0
i=1 ,ThreadName=Thread-0
i=2 ,ThreadName=Thread-0
i=0 ,ThreadName=Thread-1
i=1 ,ThreadName=Thread-1
i=2 ,ThreadName=Thread-1
end main() method
*/
Question 63.
class MyRunnable implements Runnable { public void run() { try { while (!Thread.currentThread().isInterrupted()) { Thread.sleep(1000); System.out.println("x"); } } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName() + " ENDED"); } } } public class MyClass { public static void main(String args[]) throws Exception { MyRunnable obj = new MyRunnable(); Thread t = new Thread(obj, "Thread-1"); t.start(); System.out.println("press enter"); System.in.read(); t.interrupt(); } }
Answer. "press enter" will be printed first then thread1 will keep on printing x until enter is pressed, once enter is pressed "Thread-1 ENDED" will be printed. System.in.read() causes main thread to go from running to waiting state (thread waits for user input)
/* OUTPUT
press enter
x
x
x
x
Thread-1 ENDED
*/
Question 64.
class MyRunnable implements Runnable{ public void run(){ synchronized (this) { System.out.println("1 "); try { this.wait(); System.out.println("2 "); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class MyClass { public static void main(String[] args) { MyRunnable myRunnable=new MyRunnable(); Thread thread1=new Thread(myRunnable,"Thread-1"); thread1.start(); } }
Answer. Thread acquires lock on myRunnable object so 1 was printed but notify wasn't called so 2 will never be printed, this is called frozen process. Deadlock is formed, These type of deadlocksare called Frozen processes.
/*OUTPUT
1
*/
Question 65.
import java.util.ArrayList; /* Producer is producing, Producer will allow consumer to * consume only when 10 products have been produced (i.e. when production is over). */ class Producer implements Runnable{ ArrayList<Integer> sharedQueue; Producer(){ sharedQueue=new ArrayList<Integer>(); } @Override public void run(){ synchronized (this) { for(int i=1;i<=3;i++){ //Producer will produce 10 products sharedQueue.add(i); System.out.println("Producer is still Producing, Produced : "+i); try{ Thread.sleep(1000); }catch(InterruptedException e){e.printStackTrace();} } System.out.println("Production is over, consumer can consume."); this.notify(); } } } class Consumer extends Thread{ Producer prod; Consumer(Producer obj){ prod=obj; } public void run(){ synchronized (this.prod) { System.out.println("Consumer waiting for production to get over."); try{ this.prod.wait(); }catch(InterruptedException e){e.printStackTrace();} } int productSize=this.prod.sharedQueue.size(); for(int i=0;i<productSize;i++) System.out.println("Consumed : "+ this.prod.sharedQueue.remove(0) +" "); } } public class MyClass { public static void main(String args[]) throws InterruptedException{ Producer prod=new Producer(); Consumer cons=new Consumer(prod); Thread prodThread=new Thread(prod,"prodThread"); Thread consThread=new Thread(cons,"consThread"); consThread.start(); Thread.sleep(100); //minor delay. prodThread.start(); } }
Answer. Because of minor delay delay consThread surely started before producer thread. "Consumer waiting for production to get over." printed first
than producer produced
than "Production is over, consumer can consume."
than consumer consumed.
The above program is classical example of how to solve Consumer Producer problem by using wait() and notify() methods.
/*OUTPUT
Consumer waiting for production to get over.
Producer is still Producing, Produced : 1
Producer is still Producing, Produced : 2
Producer is still Producing, Produced : 3
Production is over, consumer can consume.
Consumed : 1
Consumed : 2
Consumed : 3
*/
Question 66.
class MyRunnable implements Runnable{ public void run(){ synchronized (this) { System.out.print("1 "); try { this.wait(1000); System.out.print("2"); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class MyClass { public static void main(String[] args) { MyRunnable myRunnable=new MyRunnable(); Thread thread1=new Thread(myRunnable,"Thread-1"); thread1.start(); } }
Answer. First 1 will be printed then even if notify() or notifyAll() is not called, thread will be notified after 1000 millisec and 2 will be printed.
/*OUTPUT
1 2
*/
Question 67.
class MyRunnable implements Runnable { public void run() { System.out.println(Thread.currentThread().getName() + " has started"); try { Thread.sleep(100); //ensure that main thread don’t complete before Thread-1 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " has ended"); } } public class MyClass { public static void main(String... args) throws InterruptedException { System.out.println(Thread.currentThread().getName() + " has started"); Thread thread1 = new Thread(new MyRunnable(), "Thread-1"); thread1.start(); thread1.sleep(10000); System.out.println(Thread.currentThread().getName() + " has ended"); } }
Answer.
sleep()is a static method, causes the currently executing thread to sleep for the specified number of milliseconds.
Callingthread1.sleep(10000); will show warning - The static method sleep(long) from the type Thread should be accessed in a static way.
In the program first main thread started, than it invoked Thread-1, then Thread-1 called sleep(100) method to ensure that main thread don’t complete before Thread-1, than execution control went to main thread and it calledthread1.sleep(10000)but rather than putting Thread-1 on sleep it made main thread to sleep. And Thread-1 ended before main thread.
/*OUTPUT
main has started
Thread-1 has started
Thread-1 has ended
main has ended
*/
Question 68.
class MyRunnable1 implements Runnable{ @Override public void run(){ synchronized (this) { try{ System.out.print("2 "); Thread.sleep(1000); }catch(InterruptedException e){e.printStackTrace();} this.notify(); System.out.print("3 "); } } } class MyRunnable2 extends Thread{ MyRunnable1 prod; MyRunnable2(MyRunnable1 obj){ prod=obj; } public void run(){ synchronized (this.prod) { System.out.print("1 "); try{ this.prod.wait(); }catch(InterruptedException e){e.printStackTrace();} } System.out.print("4 "); } } public class MyClass { public static void main(String args[]) throws InterruptedException{ MyRunnable1 myRunnable1=new MyRunnable1(); MyRunnable2 myRunnable2=new MyRunnable2(myRunnable1); Thread thread1=new Thread(myRunnable1,"Thread-1"); Thread thread2=new Thread(myRunnable2,"Thread-2"); thread2.start(); Thread.sleep(100); //This minor delay will ensure that Thread-1 thread starts Thread-2 thread1.start(); } }
Answer.Wait() method causes the current thread to wait until another thread invokes the notify() or notifyAll() method for this object.
Now, as soon as notify() or notifyall() method is called it notifies the waiting thread, but object monitor is not yet available. Object monitor is available only when thread exits synchronized block or synchronized method. So, what happens is code after notify() is also executed and execution is done until we reach end of synchronized block.
/*OUTPUT
1 2 3 4
*/
Question 69.
class MyThread extends Thread { MyThread() { System.out.print("1 "); } public void run() { System.out.print("2 "); } } public class MyClass { public static void main(String[] args) { Thread thread1 = new MyThread() { public void run() { System.out.print("3 "); } }; thread1.start(); } }
Answer.
new MyThread() > created instance of an anonymous inner class.
constructor was called which printed 1
than overridden run() method of anonymous inner class was invoked, which printed 3.
/*OUTPUT
1 3
*/
Question 70.
class MyRunnable implements Runnable{ public void run(){ method(); } synchronized void method(){ for(int i=0;i<2;i++){ System.out.println(Thread.currentThread().getName()); } } } public class MyClass { public static void main(String...args){ MyRunnable runnable=new MyRunnable(); Thread thread1=new Thread(runnable,"Thread-1"); Thread thread2=new Thread(runnable,"Thread-2"); thread1.start(); thread2.start(); } }
Answer. Thread behavior is unpredictable because execution of Threads depends on Thread scheduler, either of thread1 and thread2 can start first and synchronized method will be executed by one thread at a time.
/*OUTPUT if Thread-1 entered first in synchronized block.
Thread-1
Thread-1
Thread-2
Thread-2
*/
/*OUTPUT if Thread-2 entered first in synchronized block.
Thread-2
Thread-2
Thread-1
Thread-1
*/
Question 71.
public class MyClass { public static void main(String[] args) { Thread thread1=new Thread("Thread-1"){ public void run() { synchronized (String.class) { try { Thread.sleep(100); } catch (InterruptedException e) {e.printStackTrace();} System.out.println("1 "); synchronized (Object.class) { System.out.println("2 "); } } System.out.println("3 "); } }; Thread thread2=new Thread("Thread-2"){ public void run() { synchronized (Object.class) { System.out.println("4 "); try { Thread.sleep(100); } catch (InterruptedException e) {e.printStackTrace();} synchronized (String.class) { System.out.println("5 "); } } System.out.println("6 "); } }; thread1.start(); thread2.start(); } }
Answer.Deadlock is formed in above program :
Thread-1 acquires lock on String.class and then calls sleep() method which gives Thread-2 the chance to execute immediately after Thread-1 has acquired lock on String.class and Thread-2 acquires lock on Object.class then calls sleep() method and now it waits for Thread-1 to release lock on String.class.
Conclusion:
Now, Thread-1 is waiting for Thread-2 to release lock on Object.class and Thread-2 is waiting for Thread-1 to release lock on String.class and deadlock is formed.
/*OUTPUT
4
1
*/
Question 72.
public class MyClass { public static void main(String[] args) throws InterruptedException { synchronized (args) { System.out.print("1 "); args.wait(); System.out.print("2 "); } } }
Answer.Though this question looks bit similar to 4 but intention is to show args is object and we can acquire lock on it.
Thread acquires lock on args object but notify wasn't called so 2 will never be printed, this is called frozen process.
/*OUTPUT
1
*/
Question 73.
class Class2 { void method2(String name) { for (int x = 1; x <=2; x++) { System.out.println(Thread.currentThread().getName()); } } } public class MyClass implements Runnable { Class2 obj2; public static void main(String[] args) { new MyClass().method1(); } void method1() { obj2 = new Class2(); new Thread(new MyClass()).start(); new Thread(new MyClass()).start(); } public void run() { obj2.method2(Thread.currentThread().getName()); } }
Answer. Program will face NullPointerException at Class2 obj2, we must make it static. As new Thread(new MyClass()).start(); creates thread on new instance of MyClass.
If Class2 obj2 is made static, than
Thread-0 and Thread-1 will be printed twice but in unpredictable order.
So, output will be different in subsequent executions,(as shown below)-
/*OUTPUT
Thread-1
Thread-1
Thread-0
Thread-0
*/
/*OUTPUT
Thread-0
Thread-1
Thread-1
Thread-0
*/
Question 74.
class MyRunnable1 implements Runnable{ @Override public void run(){ if(Thread.currentThread().getName().equals("Thread-1")) method1(); else method2(); } synchronized void method1(){ System.out.println(Thread.currentThread().getName() +" in synchronized void method1() started"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() +" in synchronized void method1() ended"); } synchronized void method2(){ System.out.println(Thread.currentThread().getName() +" in synchronized void method2() started"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+ " in synchronized void method2() ended"); } } public class MyClass { public static void main(String args[]) throws InterruptedException{ MyRunnable1 myRunnable1=new MyRunnable1(); Thread thread1=new Thread(myRunnable1,"Thread-1"); Thread thread2=new Thread(myRunnable1,"Thread-2"); thread1.start(); Thread.sleep(10);//Just to ensure Thread-1 starts before Thread-2 thread2.start(); } }
Answer. Here when Thread-1 is in synchronized method1() it must be holding lock on object’s monitor and will release lock on object’s monitor only when it exits synchronized method1(). So, Thread-2 will have to wait for Thread-1 to release lock on object’s monitor so that it could enter synchronized method2().
Likewise, Thread-2 even cannot enter synchronized method1() which is being executed by Thread-1. Thread-2 will have to wait for Thread-1 to release lock on object’s monitor so that it could enter synchronized method1().
/*OUTPUT
Thread-1 in synchronized void method1() started
Thread-1 in synchronized void method1() ended
Thread-2 in synchronized void method2() started
Thread-2 in synchronized void method2() ended
*/
Question 75.
class MyRunnable implements Runnable{ public void run(){ System.out.println("1 "); try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("2 "); } } public class WaitNoParaMethod { public static void main(String[] args) { MyRunnable myRunnable=new MyRunnable(); Thread thread1=new Thread(myRunnable,"Thread-1"); thread1.start(); } }
Answer.
IllegalMonitorStateException is thrown at runtime, as wait() method was called without acquiring lock on object monitor.
/*OUTPUT
1
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:503)
at o15_wait_IllegalMoni.MyRunnable.run(WaitNoParaMethod.java:9)
at java.lang.Thread.run(Unknown Source)
*/
Question 76.
public class MyClass implements Runnable{ @Override public void run() { System.out.println("1"); } public static void main(String[] args) { MyClass obj=new MyClass(); Thread thread1=new Thread(obj,"Thread-1"); thread1.start(); thread1.start(); } }
Answer. 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.
/*OUTPUT
1
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
*/
Question 77.
class MyThread extends Thread { } public class MyClass { public static void main(String[] args) { Thread thread1=new MyThread(); thread1.start(); } }
Answer. Nothing will be printed in output.
When we call start() method on thread, it internally calls run() method with newly created thread. So, if we don’t override run() method newly created thread won’t be called and nothing will happen.
Question 78.
class MyThread extends Thread { public void run() { System.out.println("1"); } public void start(){ System.out.println("2"); } } public class MyClass { public static void main(String[] args) { MyThread thread1=new MyThread(); thread1.start(); } }
Answer.When we call start() method on thread, it internally calls run() method with newly created thread. So, if we override start() method, run() method will not be called until we write code for calling run() method.
/*OUTPUT
2
*/
Question 79.
class MyRunnable1 implements Runnable{ @Override public void run(){ if(Thread.currentThread().getName().equals("Thread-1")) method1(); else method2(); } static synchronized void method1(){ System.out.println(Thread.currentThread().getName()+ " in synchronized void method1() started"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() +" in synchronized void method1() ended"); } static synchronized void method2(){ System.out.println(Thread.currentThread().getName() +" in synchronized void method2() started"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() +" in synchronized void method2() ended"); } } public class MyClass { public static void main(String args[]) throws InterruptedException{ MyRunnable1 object1=new MyRunnable1(); MyRunnable1 object2=new MyRunnable1(); Thread thread1=new Thread(object1,"Thread-1"); Thread thread2=new Thread(object2,"Thread-2"); thread1.start(); Thread.sleep(10);//Just to ensure Thread-1 starts before Thread-2 thread2.start(); } }
Answer. It might confuse you a bit that threads are created on different objects. But, not to forgot that multiple objects may exist but there is always one class’s class object lock available.
Here, when Thread-1 is in static synchronized method1() it must be holding lock on class class’s object and will release lock on class’s classobject only when it exits static synchronized method1(). So, Thread-2 will have to wait for Thread-1 to release lock on class’s classobject so that it could enter static synchronized method2().
/*OUTPUT
Thread-1 in synchronized void method1() started
Thread-1 in synchronized void method1() ended
Thread-2 in synchronized void method2() started
Thread-2 in synchronized void method2() ended
*/
Question 80.
class MyRunnable1 implements Runnable{ @Override public void run(){ if(Thread.currentThread().getName().equals("Thread-1")) method1(); else method2(); } synchronized void method1(){ System.out.println(Thread.currentThread().getName()+ " in synchronized void method1() started"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+ " in synchronized void method1() ended"); } synchronized void method2(){ System.out.println(Thread.currentThread().getName() +" in synchronized void method2() started"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() +" in synchronized void method2() ended"); } } public class MyClass { public static void main(String args[]) throws InterruptedException{ MyRunnable1 object1=new MyRunnable1(); MyRunnable1 object2=new MyRunnable1(); Thread thread1=new Thread(object1,"Thread-1"); Thread thread2=new Thread(object2,"Thread-2"); thread1.start(); Thread.sleep(10);//Just to ensure Thread-1 starts before Thread-2 thread2.start(); } }
Answer. Here when Thread-1 is in synchronized method1() it must be holding lock on object1’s monitor. Thread-2 will acquire lock on object2’s monitor and enter synchronized method2().
/*OUTPUT
Thread-1 in synchronized void method1() started
Thread-2 in synchronized void method2() started
Thread-1 in synchronized void method1() ended
Thread-2 in synchronized void method2() ended
*/
Question 81.
public class MyClass extends Thread{ public void run() { method1(); } public static void method1() { synchronized (this) { System.out.println("2 "); } } public static void main(String[] args) { new Thread(new MyClass()).start(); } }
Answer. We will face compilation error at linesynchronized (this)can’t use in static context, because it’s not possible to obtain lock on object from static method. Though we can obtain lock on class’s class object , so synchronized (MyClass.class) will be a valid statement.
Question 82.
public class MyClass { public static void main(String[] args) { System.out.println("1 "); InnerClass i=new InnerClass(); i.start(); System.out.println("2 "); } static class InnerClass extends Thread{ public void run()throws RuntimeException{ throw new RuntimeException(); } } }
Answer. Program will compile as run() method can throw RuntimeException. 1 & 2 will be present in output and will throw java.lang.RuntimeException at runtime.
/*OUTPUT
1
2
Exception in thread "Thread-0" java.lang.RuntimeException
at o22.s$InnerClass.run(s.java:13)
*/
Opinions expressed by DZone contributors are their own.
Comments