Google

Dec 19, 2011

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.


Q. Explain how you would get a Thread Deadlock with a code example?
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:

26 Comments:

Blogger sumit said...

really tough to understand..huh!

2:17 PM, June 29, 2012  
Blogger Unknown said...

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.

2:47 PM, June 29, 2012  
Blogger Unknown said...

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.

2:52 PM, June 29, 2012  
Anonymous Anonymous said...

Q 3:
class NumberGenerator
Line 26
is there i+2 or will be i+1?

4:57 PM, July 12, 2012  
Anonymous Anonymous said...

srry,now i got.

4:59 PM, July 12, 2012  
Blogger Unknown said...

i+2 will give you the next odd or even number depending on i is odd or even respectively.

5:47 PM, July 12, 2012  
Anonymous Hari said...

Hi Arul,
Awesome, one of the best site for clearly understanding about multi-threading.. Hats off to your work.

7:28 PM, August 28, 2012  
Anonymous Anonymous said...

Hard to understand,but its good

10:09 PM, August 29, 2012  
Blogger Unknown said...

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.

10:24 AM, August 30, 2012  
Blogger Unknown said...

Arul, you are simply aweosme.. Keep it up.

7:19 PM, September 14, 2012  
Anonymous Anonymous said...

Shouldn't this be 'implements Runnable'? public class NumberGenerator extends Thread {

5:17 PM, September 21, 2012  
Blogger Unknown said...

You can create a thread 2 ways. In this example, I have chosen to extend the Thread class. Generally, implements Runnable is preferred.

5:48 PM, September 21, 2012  
Anonymous Anonymous said...

Very nice examples!!! Thanks.

8:52 AM, October 08, 2012  
Blogger Unknown said...

hello sir,
please told me the process of web servce developement.

5:26 PM, October 28, 2012  
Blogger Unknown said...

how to make web servce

5:27 PM, October 28, 2012  
Anonymous Anonymous said...

Excellent!! The pipe example is awesome! very much helpful. Thanks for such a nice blog.
Keep posting :)

9:04 PM, December 18, 2012  
Anonymous Anonymous said...

Very nice explanation i have ever seen ....

3:48 PM, August 02, 2013  
Blogger Unknown said...

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.

9:26 PM, September 04, 2013  
Blogger Unknown said...

static means a class level lock as opposed to an object or block level locks.

2:01 AM, September 05, 2013  
Blogger Unknown said...

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();
}

}

11:12 PM, November 22, 2013  
Blogger Unknown said...

This comment has been removed by the author.

12:40 PM, November 24, 2013  
Anonymous Anonymous said...

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

6:32 AM, December 10, 2013  
Anonymous Anonymous said...

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

6:41 AM, December 10, 2013  
Blogger Unknown said...

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

10:54 AM, December 10, 2013  
Anonymous FromIndiaWithLove said...

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.

8:40 AM, July 29, 2014  
Blogger Unknown said...

There are other simpler examples here and elsewhere on the net. You can't always dwell on simpler examples.

9:54 AM, July 29, 2014  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home