Java multi-threading interview questions and answers - coding
The Java multi-threading questions are very popular with the job interviewers as it can be not only hard to grasp, but also concurrency issues are very hard to debug and fix. So, it really pays to have people with the good understanding in this key area. We looked at some basic questions and answers at Java multi-threading questions and answers. Let's look at more coding based questions and answers to build up on what we had learned before. |
A. The example below causes a deadlock situation by thread-1 waiting for lock2 and thread-0 waiting for lock1.
package deadlock; public class DeadlockTest extends Thread { public static Object lock1 = new Object(); public static Object lock2 = new Object(); public void method1() { synchronized (lock1) { delay(500); //some operation System.out.println("method1: " + Thread.currentThread().getName()); synchronized (lock2) { System.out.println("method1 is executing .... "); } } } public void method2() { synchronized (lock2) { delay(500); //some operation System.out.println("method1: " + Thread.currentThread().getName()); synchronized (lock1) { System.out.println("method2 is executing .... "); } } } @Override public void run() { method1(); method2(); } public static void main(String[] args) { DeadlockTest thread1 = new DeadlockTest(); DeadlockTest thread2 = new DeadlockTest(); thread1.start(); thread2.start(); } /** * The delay is to simulate some real operation happening. * @param timeInMillis */ private void delay(long timeInMillis) { try { Thread.sleep(timeInMillis); } catch (InterruptedException e) { e.printStackTrace(); } } }
The output will be something like:
method1: Thread-0 method1 is executing .... method2: Thread-0 method1: Thread-1 ---deadlock ----- can't proceed further
Q. What happens if you restart a thread that has already started?
A. You will get the following exception
Exception in thread "main" java.lang.IllegalThreadStateException at java.lang.Thread.start(Thread.java:595) at deadlock.DeadlockTest.main(DeadlockTest.java:38)
Q. Can you write a program with 2 threads, in which one prints odd numbers and the other prints even numbers up to 10?
A. In Java, you can use wait( ) and notifyAll( ) to communicate between threads. The code below demonstrates that.
Firstly, create the thread classes and the main method that creates the thread and run it.
package multithreading; public class NumberGenerator extends Thread { private NumberUtility numberUtility; private int maxNumber; private boolean isEvenNumber; public NumberGenerator(NumberUtility numberUtility, int maxNumber, boolean isEvenNumber) { this.numberUtility = numberUtility; this.maxNumber = maxNumber; this.isEvenNumber = isEvenNumber; } public void run() { int i = isEvenNumber == true ? 2 : 1; while (i <= maxNumber) { if(isEvenNumber == true) { numberUtility.printEven(i); } else { numberUtility.printOdd(i); } i = i + 2; } } public static void main(String[] args) { NumberUtility numUtility = new NumberUtility(); //single instance shared by oddGen and evenGen threads final int MAX_NUM = 10; //create 2 threads, one to generate odd numbers and the other to generate even numbers NumberGenerator oddGen = new NumberGenerator(numUtility, MAX_NUM, false); NumberGenerator evenGen = new NumberGenerator(numUtility, MAX_NUM, true); oddGen.start(); //start the thread - invokes the run() method on NumberGenerator evenGen.start(); //start the thread - invokes the run() method on NumberGenerator } }
Next, create the utility class that is used for communicating between the two threads with wait() and notifyAll() methods via synchronized methods.
package multithreading; import static java.lang.System.out; public class NumberUtility { boolean oddPrinted = false; public synchronized void printOdd(int number) { while (oddPrinted == true) { try { wait(); // waits until notified by even thread } catch (InterruptedException e) { e.printStackTrace(); } } out.println("printOdd() " + number); oddPrinted = true; notifyAll(); //notify all waiting threads } public synchronized void printEven(int number) { while (oddPrinted == false) { try { wait(); //waits until notified by the odd thread } catch (InterruptedException e) { } } oddPrinted = false; out.println("printEven() " + number); notifyAll(); //notify all waiting threads } }
The output will be something like
printOdd() 1 printEven() 2 printOdd() 3 printEven() 4 printOdd() 5 printEven() 6 printOdd() 7 printEven() 8 printOdd() 9 printEven() 10
Note: This a typical example of splitting tasks among threads. A method calls notify/notifyAll( ) as the last thing it does (besides return). Since the printOdd( ) and printEven( ) methods were void, the notifyAll( ) was the last statement. If it were to return some value, the notifyAll( ) would have been placed just before the return statement.
Q. Write a multi-threaded Java program in which, one thread generates odd numbers and write to a pipe and the second thread generates even numbers and write to another pipe, and a third thread receives the numbers from both the pipes and evaluates if the sum is multiples of 5?
A. In Unix, a pipe (“|”) operator helps you to redirect output from one command to another. PipedReader and PipedWriter classes in java.io package helps you to do the same. It helps you to redirect the read input into writer seamlessly. In Unix, two different processes on different address spaces can communicate using pipe, but in java two threads on the JVM can communicate using Piped ByteStream/CharacterStream within the same process (i.e same address space)
Here is the code snippet. The Writer threads responsible for writing odd and even numbers to the respective pipes.
package multithreading; import java.io.IOException; import java.io.PipedWriter; public class NumberWriter extends Thread { private PipedWriter writer; private int maxNumber; private boolean isEvenNumber; public NumberWriter(PipedWriter writer, int maxNumber, boolean isEvenNumber) { this.writer = writer; this.maxNumber = maxNumber; this.isEvenNumber = isEvenNumber; } public void run() { int i = 1; while (i <= maxNumber) { try { if (isEvenNumber && (i % 2) == 0) { writer.write(i); } else if (!isEvenNumber && i%2 != 0) { writer.write(i); } ++i; } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) { final int MAX_NUM = 10; PipedWriter oddNumberWriter = new PipedWriter(); PipedWriter evenNumberWriter = new PipedWriter(); NumberWriter oddGen = new NumberWriter(oddNumberWriter, MAX_NUM, false); NumberWriter evenGen = new NumberWriter(evenNumberWriter, MAX_NUM, true); NumberReceiver receiver = new NumberReceiver(oddNumberWriter, evenNumberWriter); oddGen.start(); evenGen.start(); receiver.start(); } }
The receiver thread that listens to both odd and even number pipes and computes the sum. If the sum is a multiple of 5, it prints the numbers and the sum.
package multithreading; import java.io.IOException; import java.io.PipedReader; import java.io.PipedWriter; public class NumberReceiver extends Thread { private PipedReader oddReader; private PipedReader evenReader; public NumberReceiver(PipedWriter oddWriter, PipedWriter evenWriter) { try { this.oddReader = new PipedReader(oddWriter); this.evenReader = new PipedReader(evenWriter); } catch (IOException e) { e.printStackTrace(); } } public void run() { int odd =0, even=0; try { while (odd != -1) { odd = oddReader.read(); even = evenReader.read(); if ((odd + even) % 5 == 0) { System.out.println("match found " + odd + " + " + even + " = " + (odd + even)); } } } catch (IOException e) { System.exit(1); } } }
The output will be something like
match found 7 + 8 = 15
Note: The above problem can also be solved with a blocking queue as described in multi-threading with blocking queues questions and answers.
Java multi-threading interview questions and answers: overview
Java multi-threading questions and answers with blocking queue
Labels: Multi-threading
26 Comments:
really tough to understand..huh!
Multithreading is hard. Try to write smaller programs first. If you Google, you will find simpler examples. The ones I have used are more real life examples.
Even many developers with experience don't get it right or fully understand. If you write the above working code and run it, you will understand it better.
Q 3:
class NumberGenerator
Line 26
is there i+2 or will be i+1?
srry,now i got.
i+2 will give you the next odd or even number depending on i is odd or even respectively.
Hi Arul,
Awesome, one of the best site for clearly understanding about multi-threading.. Hats off to your work.
Hard to understand,but its good
Multithreading is not easy. Even so called experienced programmers don't get it right. Practice the code and post any specific questions you may have.
Arul, you are simply aweosme.. Keep it up.
Shouldn't this be 'implements Runnable'? public class NumberGenerator extends Thread {
You can create a thread 2 ways. In this example, I have chosen to extend the Thread class. Generally, implements Runnable is preferred.
Very nice examples!!! Thanks.
hello sir,
please told me the process of web servce developement.
how to make web servce
Excellent!! The pipe example is awesome! very much helpful. Thanks for such a nice blog.
Keep posting :)
Very nice explanation i have ever seen ....
Hi Arul,
I have a question or need a clarity in the concept,
In the above "DeadlockTest" example why have you declared Objects as "static".
When I take off the static keyword it is not creating a Deadlock situation. Can you please throw some light to clarify the concept for me.
static means a class level lock as opposed to an object or block level locks.
Very good article, gives lot of understanding about using wait(), notify(). Here is the simplifies version of the code for the above problem to generate odd and even numbers.. might be useful for somebody looking for a simpler understanding of synchronization, wait(), notify()
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.threads;
/**
*
* @author Vyshu
*/
public class OddEven implements Runnable {
private boolean isPrint = true;
private int num =1;
public void run(){
printOddEven();
}
public synchronized void printOddEven(){
while(num<=10){
System.out.println("Thread "+Thread.currentThread().getName()+" "+num);
num++;
try{
this.notifyAll();
if(num>10){
return;
}
else{
this.wait();
}
}
catch(InterruptedException e){
}
}
}
public static void main(String args[]){
OddEven obj = new OddEven();
Thread t1 = new Thread(obj);
Thread t2 = new Thread(obj);
t1.start();
t2.start();
}
}
This comment has been removed by the author.
Hi Arul,
Why NumberReceiver and NumberWriter example didn't find the other possibilites such as 2+3, 3+7, 4+6, 5+5, 2+8..?
Thanks,
Ravi
In continuation to my previous question..
1+4, 3+2, 7+3 are possible combinations. why these are not showing.. all other possibilities are not possible as they are not odd number +even number % != 0
Thanks,
Ravi
Hi Ravi,
I think the numbers need to be consecutive numbers like
1+2 = 3, 3+4=7, 5+6=11, 7+8=15, 9+10 = 19, and so on.
It is a trivial example to demonstrate multi-threading
What Sumit is saying is right. Whats hard is the way you have written it, not the concept of multithreading. Java on average is a simple invention - no genius in it. Its not rocket science.
There are other simpler examples here and elsewhere on the net. You can't always dwell on simpler examples.
Post a Comment
Subscribe to Post Comments [Atom]
<< Home