2

In an interview today I was asked a question I could not solve:

Let's say there are three threads named T1 ,T2 and T3. Now T1 will print the numbers from 1 to 5, T2 will print the numbers from 6 to 10 and T3 will print the numbers from 10 to 15. The three threads have been started by say t1.start(), t2.start()and t3.start(), but the T3 thread should be executed first, then the T1 thread, and lastly the T2 thread should be executed.

Please advise on possible approaches to this problem. As per my research there is the concept of Thread.join, or cyclic barriers. Please advise on the best approach, and if possible please show a small piece of code for better understanding.

madth3
  • 7,275
  • 12
  • 50
  • 74
user2094103
  • 685
  • 3
  • 7
  • 14
  • 4
    Try something. But the question is a bit stupid. The best thing to do in this case is to rewrite the code and use a single thread which prints all the values in the appropriate order, since nothing is done in parallel. – JB Nizet Feb 22 '13 at 17:24
  • @JohnKane I agree with you but could you please advise if any how this the requirement then how we would proceed,Thanks in advance – user2094103 Feb 22 '13 at 17:36
  • @JBNizet I completely agree with you could you please let me know if any how this the requirement then How would I approach towards the solution ,Thanks in advance. – user2094103 Feb 22 '13 at 17:38
  • 1
    I'm pretty sure that the right answer to that question is to question the sanity of the person asking the question. – Aurand Feb 22 '13 at 17:49
  • @user2094103: the answer from Sean Landsman is a good one. I upvoted. And indeed a CountDownLatch is another solution I thought about. – JB Nizet Feb 22 '13 at 18:01
  • @JBNizet could you please show how it can be simplified through countdown latch implementation.Thanks in advance – user2094103 Feb 22 '13 at 18:04
  • No. Read the documentation, and try something by yourself. It would not be simplified. It would just use a higher-level abstraction, and would be very similar to Sean's answer. – JB Nizet Feb 22 '13 at 18:09
  • @JBNizet I have read the following url http://javarevisited.blogspot.in/2012/07/countdownlatch-example-in-java.html but stil not able to convert this into countdownlatch one,Please advise – user2094103 Feb 22 '13 at 18:13
  • 2
    Read the [CountDownLatch API documentation](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CountDownLatch.html). It has the complete reference doc, as well as examples. And take more than 10 minutes to read carefully and try something. That's how you learn. – JB Nizet Feb 22 '13 at 18:35
  • I agree with @JB Nizet, interview questions like this (from my experience at least) are attempting to see how much knowledge you have in a given area/areas and how well you think on your feet. The best way to answer them is to just learn all you can about it. For example, say you answered and explained how to do it with a count down latch. They might respond by asking why you decided to go that route over a cyclic barrier. They might also change the desired behavior to see how you change your response. For example, what would you do differently if they asked for a non-blocking solution? – John Kane Feb 22 '13 at 19:21

2 Answers2

3

I agree that this question isn't great, but as you do want some sort of answer...

This prints out 10-15, 1-5, 6-10, as per your requirement (T3 then T1 then T2) (btw - should T3 actually print from 11 to 15?):

public class Test {
  static class Printer implements Runnable {
    private final int from;
    private final int to;
    private Thread joinThread;

    Printer(int from, int to, Thread joinThread) {
      this.from = from;
      this.to = to;
      this.joinThread = joinThread;
    }

    @Override
    public void run() {
      if(joinThread != null) {
        try {
          joinThread.join();
        } catch (InterruptedException e) { /* ignore for test purposes */ }
      }
      for (int i = from; i <= to; i++) {
        System.out.println(i);
      }
    }
  }
  public static void main(String[] args) throws InterruptedException {

    Thread T3 = new Thread(new Printer(10, 15, null));
    Thread T1 = new Thread(new Printer(1, 5, T3));
    Thread T2 = new Thread(new Printer(6, 10, T1));
    T1.start();
    T2.start();
    T3.start();
  }
}

CountdownLatch is also a good alternative here perhaps.

Sean Landsman
  • 7,033
  • 2
  • 29
  • 33
  • 1
    I think they may have been looking for ways to control the output other than just starting threads and letting them run. I could be wrong though. – John Kane Feb 22 '13 at 17:45
  • Having thought about it and read some of the other comments here it may well be that they werent actually after a real implementation, but rather expecting you so question the requirement to have 3 different Threads. This is good point raised I think. – Sean Landsman Feb 22 '13 at 17:46
  • @JohnKane Agreed, that is entirely possible. Something that could have been clarified I guess during the interview – Sean Landsman Feb 22 '13 at 17:47
  • @SeanLandsman could you please explain the logic also.Thanks in advance – user2094103 Feb 22 '13 at 18:08
  • Sure, will do so as soon as I can (I'm out at the moment). In the meantime though I do think its worth considering @JohnKanes point here too – Sean Landsman Feb 22 '13 at 18:13
  • @user2094103 in a nutshell, the code is waiting for the joinThread (if not null) to die before continuing - this is achieved with join mechanism. So T2 waits for T1 to die, and T1 waits for T3 to die. T3 doesnt have to wait for any thread so it just runs to completion. If you want more information it may be an idea to move this to the chat forum. :-) – Sean Landsman Feb 22 '13 at 20:53
  • @SeanLandsman - I wonder if this user's [other question](http://stackoverflow.com/questions/15030808/regarding-countdown-latch-implementation) looks familiar to you?... – Krease Mar 03 '13 at 08:02
  • @Chris :-) its certainly related - I guess once this version was understood the OP wanted to know how to implement the other options suggested – Sean Landsman Mar 03 '13 at 08:13
0

There is no real best approach. They were most likely, looking to see how you attempt to answer the question.

When dealing with vague questions like this, I would first try to really determine what they are looking for. Do they need to execute in order? printing out the numbers in sequence, or does t3 need to print (10-15) while the other two threads wait. Or do they just need to start in the order directed and print out whenever they get to it. Reading the question as its stated seems to be just having each thread print out a defined sequence, after starting them in a defined order. That says nothing about blocking. You could just make a wrapper class holding a priority, stick them in a ordered queue, and iterate through the collection starting each thread.

I think that they may also have been looking for you to say something about the fact that it doesnt make sense to use multiple threads (assuming they want the numbers sequential) in this case, since regardless of anything else two of the three threads are doing nothing. It would be faster to only use one thread. Then add something about it might be more efficient to use some sort executor service where each thread could pull the next number to write out of a common sorted resource. then you could go into ways to protect the queue to ensure that only one is removed/written at a time. There are a lot of ways to do this, and a lot of issues with each. It also might have been good to mention something about the benefits/costs of blocking vs non-blocking as well. Since there are many different ways to do this, it probably makes sense to just familiarize yourself with the Concurrencys api.

The Concurrency util classes in Java are pretty well documented and in most cases give useful examples. This is a good place to start. Try taking a look at Semaphores,Phasers, or A Count Down Latch for this. Though, in practice Executors or The Fork/Join Framework might be worth looking into a little more.

Sorry about all that rambling but the point that I am trying to make is that there is no one best way to answer something like this. I think what this question was really about was trying to see your approach. Asking for code example will not really help you that much. Just take some time and sit down and read through some good tutorials.

John Kane
  • 4,383
  • 1
  • 24
  • 42