13

How will you execute Three threads sequentially? For eg. Thread1, Thread2, Thread3. It is not possible to pass the reference of one Thread to the other and invoke from the run() method.

So code should be like this:

 Thread1.start();
 Thread2.start();
 Thread3.start();

and out put should be

 Printing Thread1
 Printing Thread2
 Printing Thread3

This can be possible by using ThreadPoolExecutor and using a blocking queue but even that is not an acceptable answer.

5
  • please write some details about if you are able to modify the threads' bodies. Commented Mar 28, 2011 at 16:15
  • @xappy: You are free to implement a solution but I doubt he was expecting passing thread references or using wait()/notify(). I was made to feel there was a obvious solution that I didn't know. Commented Mar 28, 2011 at 16:24
  • but.. At the same time on the contrary they could expect that you provide them exactly solution with wait()/notify() (or another synchronization mechanism). It will show that you do really understand how to synchronize threads. In our multicore age it is very important to understand synchronization issues and such knowledge is appreciated not less than just smartness. Commented Mar 28, 2011 at 16:28
  • "... even that is not an acceptable answer." Why on earth not? These questions are always incomprehensible. If you want sequentiality, why are you using threads? Commented Jun 13, 2016 at 10:42
  • Sequence printing of n thread: stackoverflow.com/a/55932508/1216775 Commented May 1, 2019 at 6:41

14 Answers 14

17

You could use Executors.newSingleThreadExecutor(), but strictly speaking this launches only one Thread, so may not be expected solution.

The simpliest solution using just Thread class:

Thread1.start();
Thread1.join();
Thread2.start();
Thread2.join();
Thread3.start();
Thread3.join();

(I omitted exception handling for clarity, Thread.join() can throw InterruptedException)

Sign up to request clarification or add additional context in comments.

6 Comments

But OP needs that all three threads were launched in row without any code between start()s .
I disagree. The question is a little ambigious, but I think I got it the right way. If they are started in a row then you would have to modify run() method to synchronize them somehow and I think this interview question was not about it.
I don't know what does Geek's interviewer wants, but I just see three sequential calls of start() method and the needed output.
Even if we start the threads sequentially, but still how we be sure that the same order will be followed by the thread sheduler. If the Thread Scheduler chooses to run Thread2 first then this solution won't work.
There is no ambiguity in the question. The user wants to start a thread, execute its code and then do the some for the other afterwards.
|
11

Use ExecutorService in java.util.concurrent package. More precisely use Executors.newSingleThreadExecutor();

1 Comment

There is not much difference between ThreadPoolExecutor and ExecutorService since ThreadPoolExecutor is a ExecutorService.
11

The simplest answer is

Thread1.run();
Thread2.run();
Thread3.run();

The problem with unrealistic questions is they often have an uninformative answer. ;)

The whole point of having threads is to run them concurrently. If you are not doing that at all, don't use threads.

You might say that; you cannot call the run() method, in which case you cannot use ThreadPoolExecutor because it calls the run() method for you. i.e. thats what submit() eventually does.

EDIT: The results are completely deterministic, becaus ethe fact that there is a Thread involved is irrelivent.

static class PrintThread extends Thread {
    public PrintThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++)
            System.out.println(getName() + ": " + i);
    }
}

public static void main(String args[]) {
    Thread thread1 = new PrintThread("A");
    Thread thread2 = new PrintThread("B");
    Thread thread3 = new PrintThread("C");

    thread1.run();
    thread2.run();
    thread3.run();
}

Prints

A: 0
A: 1
.. deleted ..
C: 98
C: 99

as expected.

9 Comments

Well, but the result of this code will not be as expected on any multicore machine:)
It is also not the truth. If threads had to print more than one line (for example, print 100 strings in loop) then result is unpredictable. Even on a single core machine.
I like the answer. I think it is the right answer to the wrong question :-)
How is it unpredictable? Can you give an explaination for this?
@xappy: You're just wrong. run doesn't run as a new thread, it runs the thread's logic from the invoking thread. Maybe you're confusing run() with start()? They will be run sequentially, however it doesn't execute the three threads per se so I'm not sure it exactly answers the question.
|
5

Since this is an interview question, they're looking for specific knowledge, not a "well it's obviously better to do it this way" answer. It also seems that they'll likely strike out solution after solution until they get the answer they want.

Odds are they want to see if you can implement inter-thread communications yourself. But they don't want you to do it the easy way (thread references available). Otherwise, you could just do thread.join().

So have all three threads grab some bit of shared memory (synchronized static class). Have each thread check a public static int nextThread(). Upon successful comparison that they are the next thread, they should do their work and update public static setNextThread(int value) with the value of the next thread to be processed.

The key is to do this in a thread-safe manner; however, if you can guarantee unique thread identifiers and ensure that no two threads have the same identifier, you can (with careful coding) even manage to do this without synchronization.

Comments

5

Threads can be executed sequentially by using ExecutorService. Find below example.

public class SeqThread {

    public static void main(String[] arg) {
          new SeqThread().execute();
    }

    public void execute() {
        try {
        ExecutorService executor = Executors.newFixedThreadPool(1);
        executor.submit(R);
        executor.submit(R2);
        executor.shutdown();

            executor.awaitTermination(10, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    Runnable R = new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i=0;i<10;i++)
            {
                System.out.println("In Thread One "+i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    };

    Runnable R2 = new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i=0;i<10;i++)
            {
                System.out.println("In Thread Two="+i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    };
}

Comments

4

If it were not related to various ways of invoking these threads, theoretically, they should use acquire a common sempahore, and release it when done printing.
JDK has an inbuilt semaphore.

2 Comments

This makes sure they don't run in parallel, but that doesn't mean they run sequentially (i.e. Thread 2 could run before Thread 1) if it were the threads themselves that acquire the semaphore.
+1, @Mark, true. To solve this, the semaphore can be made fair download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/…
2

Forcing threads to run in ordered manner is like killing the very concept of multithreading, its more like single threaded program' sub-routine execution. As its interview question so everything is OK. Here is the program that test the logic not with 4 but 50 threads-

public class Outer {
    private Thread[] jobs;
    private String[] names;
    private int indx;

public Outer(int numOfThreads) {
    jobs = new Thread[numOfThreads];
    names = new String[numOfThreads];
    indx = numOfThreads - 1;
}

class Inner implements Runnable {
public void run() {
    while (true) {
       if (names[indx].equals(Thread.currentThread().getName())) {
          indx--;
          break;
       }
       else {
          try { Thread.sleep(20); } catch(InterruptedException ie) {}
       }
    }
    // now current thread will join behind the previous one..
    if (indx >= 0) try { jobs[indx].join(); } catch(InterruptedException ie) {}

    /***** YOUR ACTUAL CODE GOES FROM HERE *****/

    // at last check is it working ?
    System.out.println(Thread.currentThread().getName());
  }
}

public void f() {
    Inner target = new Inner();
    // initializing all threads..
    for (int i = 0; i < jobs.length; jobs[i++] = new Thread(target));
    for (int i = 0; i < names.length; names[i] = jobs[i++].getName());

    // checking name of threads..
    for (int i = 0; i < names.length; System.out.println(names[i++]));

    System.out.println();

    // now we start all threads..
    for (int i = 0; i < jobs.length; jobs[i++].start());
  }

public static void main(String[] args) {
    new Outer(50).f();               // testing logic not with 4 but 50 threads..
  }
}

1 Comment

Truly inventive, but I agree with your first comment.
1

You can find everything there: http://download.oracle.com/javase/tutorial/essential/concurrency/index.html

Especially read about notifications and synchronization between threads.

P.S. And remember, even if you pass the interview you'll still had to work! :)

(Ok, I'll give some hints: look the description of such methods as Object.wait() and Object.notifyAll() it is the simpliest but also very usefull mechanism)

9 Comments

You'd be crazy to use wait/notify for such a simple problem. Not to mention the fact that you'd have to rewrite your thread logic to use it.
@xap: that will work with some clever or say bad boolean flags, I understand wait(), notify(). Idoubt the interviewer was looking for that. :-)
@Mark : "You'd be crazy" is not appropriate. We are just discussing a question. Hang on, some one might give a clever hack.
@Mark, I just answered the question how to run 3 different threads so they executed their code sequentially. And I think this mechanism is the simpliest one (boolean flags are not thread safe).
@Mark, if you don't mind, I'll provide my answer by words. Here is two "lock objects" and three threads. The second thread just waits at the beginning of the execution on the first "lock" and the third thread - on the second "lock". The first thread executes its code and notifies all threads using the first lock. Then, the second thread at the end of its execution notifies all waiters on the second lock. That is.
|
1

newSingleThreadExecutor. A single-threaded executor creates a single worker thread to process tasks, replacing it if it dies unexpectedly. Tasks are guaranteed to be processed sequentially according to the order imposed by the task queue (FIFO, LIFO, priority order).

Comments

0

This could be a trick question. Maybe they don't want to hear the solution to this specific problem but want you to back track to the source of the problem and come up with a better solution.

Comments

0

I've used basic thread communication model and it could be more simplified as well. Let's say you have 3 threads, one is printing 0, second one is printing odd number and third one is printing even number liker this 01 02 03 04 05....

public class app{
        int status=0;
        public static void main(String[] args) throws InterruptedException{

            app obj = new app();
            Thread t1 = new Thread(new print(obj,0));
            Thread t2 = new Thread(new print(obj,1));
            Thread t3 = new Thread(new print(obj,2));
                t1.start();t2.start();t3.start();
            }

    }
    class print implements Runnable{
        app obj;
        int a;
        public print(app obj, int a) {
            this.obj=obj;
            this.a=a;
        }
        @Override
        public void run() {
            try{

                if(a==0){
                    synchronized(obj){
                    for (int i = 0; i < 21; i++) {
                        while(obj.status!=0 && obj.status!=3){
                            obj.wait();
                            } 

                        System.out.print(0);
                        if(obj.status==0)//even sets status to 0 so next one is odd
                            obj.status=1;
                        else//odd sets status to 3 so next one is even
                            obj.status=2;
                        obj.notifyAll();
                        }
                    }
                }
                    else if(a%2!=0){
                        synchronized (obj) {
                            for (int i = 0; i < 11; i++) {
                                while(obj.status!=1){
                                    obj.wait();
                                    } 

                                System.out.print(a);
                                a+=2;
                                obj.status=3;
                       //3 decides 0 came after odd, so next one           
                      //after zero is even
                                obj.notifyAll();
                            }
                        }
                    }
                    else{
                        synchronized (obj) {
                            for (int i = 0; i < 11; i++) {
                                while(obj.status!=2){
                                    obj.wait();
                                    } 

                                System.out.print(a);
                                a+=2;
                                obj.status=0;
                                obj.notifyAll();
                            }
                        }
                    }
                }




            catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                }
            }
        }

Comments

0

I am not sure if I understood the question completely but this seems like a situation where we want to print the threads in sequence. One example is to print the value using threads in a sequence like:

Thread - 0 output: 1

Thread - 1 output: 2

Thread - 2 output: 3

Thread - 0 output: 4

Thread - 1 output: 5

Thread - 2 output: 6 and so on..

If this is the requirement then a generic solution for n threads can be written where each thread will wait for its turn (using common object on which it will try to acquire lock).

class ResourceLock {
    private volatile int currentThreadId;
    private final int totalThreads;

    public ResourceLock(int threadsCount) {
        this.currentThreadId = 0;
        this.totalThreads = threadsCount;
    }
    public void assignTokenToNextThread(int currentThreadNum) {
        this.currentThreadId = (currentThreadNum + 1) % totalThreads;
    }
    public int getCurrentThreadId() {
        return currentThreadId;
    }
}

Now a worker thread will do its job and use the instance of above class for locking purpose:

class Worker extends Thread {
    private final ResourceLock resourceLock;
    private final int threadId;                     // id of this thread
    private final AtomicInteger counter;            // counter shared by all threads, will print number in sequence.
    private volatile boolean running = true;        // flag to stop this thread when necessary
    public Worker(ResourceLock resourceLock, int threadNumber, AtomicInteger counter) {
        this.resourceLock = resourceLock;
        this.threadId = threadNumber;
        this.counter = counter;
    }
    @Override
    public void run() {
        while (running) {
            try {
                synchronized (resourceLock) {
                    while (resourceLock.getCurrentThreadId() != this.threadId) {
                        resourceLock.wait();
                    }
                    System.out.println("Thread:" + threadId + " value: " + counter.incrementAndGet());
                    Thread.sleep(1000);
                    resourceLock.assignTokenToNextThread(this.threadId);
                    resourceLock.notifyAll();
                }
            } catch (Exception e) {
                System.out.println("Exception: " + e);
            }
        }
    }
    public void shutdown() {
        running = false;
    }
}

And this can be tested as:

public static void main(String[] args) throws InterruptedException {
        final int threadsCount = 3;
        final ResourceLock lock = new ResourceLock(threadsCount);
        Worker[] threads = new Worker[threadsCount];
        final AtomicInteger counter = new AtomicInteger(0);
        for(int i=0; i<threadsCount; i++) {
            threads[i] = new Worker(lock, i, counter);
            threads[i].start();
        }
        Thread.sleep(20000);
        System.out.println("Will try to shutdown now...");
        for(Worker worker: threads) {
            worker.shutdown();
        }
    }

Comments

0

By following approach we can run threads in sync Using synchronized methods here I used thread and runnable for running threads in SYNC:

public class FinnocciSeries {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Thread th = new Thread(new FinnocciSeriesImpl(10));
    th.start();
    //th.join(); 
    FinnocciSeriesThreadImpl thbyTh= new FinnocciSeriesThreadImpl(5);
    thbyTh.start();
      }
   }
class FinnocciSeriesImpl implements Runnable{
private int num;
public FinnocciSeriesImpl(int num) {
    this.num = num;
}
@Override
public void run() {
    // TODO Auto-generated method stub
    fib();
    
}
public synchronized static void fib() {  // this method responsible for sync
    int a,b,c,n;
    a=0;b=1;c=1;n=10;
    for(int i =0; i<=n;i++) {
        System.out.println(a + " from Runnable  ");//0,1,3
        a=b;// 0=> 1,1,2
        b=c; // 1=>1,2,3,
        c=a+b; //1=>2,3,5
     }
   }
 }


class FinnocciSeriesThreadImpl extends Thread{
private int num;
public FinnocciSeriesThreadImpl(int num) {
    this.num = num;
}
@Override
public void run() {
    // TODO Auto-generated method stub
    int a,b,c,n;
    a=0;b=1;c=1;n=10;
    for(int i =0; i<=n;i++) {
        System.out.println(a + "  from thread ");//0,1,3
        a=b;// 0=> 1,1,2
        b=c; // 1=>1,2,3,
        c=a+b; //1=>2,3,5
    }
    
}
}

Comments

-4
public static void main(String[] args)throws InterruptedException {

    MyRunnable r = new MyRunnable();
    Thread t1 = new Thread(r,"A");
    Thread t2 = new Thread(r,"B");
    Thread t3 = new Thread(r,"C");
    t1.start();
    Thread.sleep(1000);
    t2.start();
    Thread.sleep(1000);
    t3.start();



}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.