0

I want the threads to run in a particular order. Suppose I have three thread T1, T2, T2 .

T1 prints 0
T2 prints 1
T3 prints 2

I want the output in the order 0 1 2, 0 1 2 for certain number of time.

If there are two threads T1 and T2. Printing 0 1, 0 1... can be done using Producer-Consumer Problem using synchronization.

Pradeep Kr Kaushal
  • 1,506
  • 1
  • 16
  • 29

4 Answers4

2

Create a class UnitOfWork:

public class UnitOfWork implements Runnable
{
    String text;

    public UnitOfWork(String text){
        this.text = text;
    }

    public void run(){
        System.out.println(text);
    }
}

And then create a single thread executor service:

ExecutorService executor = ExecutorService.newSingleThreadExecutor();

which you will use like this:

UnitOfWork uow0 = new UnitOfWork("0");
UnitOfWork uow1 = new UnitOfWork("1");
UnitOfWork uow2 = new UnitOfWork("2");

for(int i = 0; i < 5; i++){
    executor.submit(uow0);
    executor.submit(uow1);
    executor.submit(uow2);
}

When you are unhappy with the single thread, you can start using multiple thread executor service, which will in fact run tasks concurrently.

Jakub Zaverka
  • 8,816
  • 3
  • 32
  • 48
  • 1
    OP, if this is all you asked for, then you didn't need any threads, just as indicated to you above. `executor.submit()` in this case just directly calls `UnitOfWork.run()`. – Marko Topolnik Jan 14 '14 at 12:08
  • @MarkoTopolnik nope, SingleThreadExecutor creates a new thread, which will not change, to execute all the task. I have a working app that relies on this fact. – Jakub Zaverka Jan 14 '14 at 14:34
  • Yes, you are right---you hand over the task to the other thread, and the work of *that* thread is just calling `run` of all the submitted tasks in turn. Unless you need the main thread to do something else, that fact is just overhead. – Marko Topolnik Jan 14 '14 at 14:35
1

Using the method join() in the thread class you can achieve this.

The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing,

t.join();

causes the current thread to pause execution until t's thread terminates. Overloads of join allow the programmer to specify a waiting period. However, as with sleep, join is dependent on the OS for timing, so you should not assume that join will wait exactly as long as you specify.

Like sleep, join responds to an interrupt by exiting with an InterruptedException.

Typo
  • 1,875
  • 1
  • 19
  • 32
  • look google did it http://docs.oracle.com/javase/tutorial/essential/concurrency/join.html – Typo Jan 14 '14 at 10:39
  • @Juan `join` certain that until the threads terminates another should wait. – Pradeep Kr Kaushal Jan 14 '14 at 10:42
  • @Pradeep I don't understand your comment. But yes if you use threads and you want a particular order in execution you need to join them, otherwise there's no guarantee that the finish order would be the required one. – Typo Jan 14 '14 at 10:44
  • OP doesn't wath the threads to *finish* in order, but to *print* in order. – Marko Topolnik Jan 14 '14 at 11:01
  • @Marko Topolnik I don't see the conflict, none of us knows what the duration is or the process implications that each thread has. – Typo Jan 14 '14 at 11:04
  • Actually, everybody who has read the question knows it: "I want the output in the order 0 1 2, 0 1 2 for certain number of time." Each thread has its own digit to print -> draw your conclusion from there. – Marko Topolnik Jan 14 '14 at 11:05
  • @Marko Topolnik, that's the result expected for each thread. It doesn't make any sense to create three threads just to print numbers, is reasonably to assume there's something more envolved in the process. Yet I stand by my answer. – Typo Jan 14 '14 at 11:09
1

Use Thread.join to ensure it terminates before the next thread starts.

public static void main(String[] args) throws InterruptedException {
        final Thread th1 = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("Thread 1");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread th2 = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("Thread 2");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread th3 = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("Thread 3");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        th1.start();
        th1.join();
        th2.start();
        th2.join();
        th3.start();
    }
PKopachevsky
  • 262
  • 1
  • 6
0

This is a minimalist piece of code which does literally what you asked for. It relies on the wait-notify mechanism.

I stand by my assesment that you do not need any threads to meet your requirement. A simple loop which prints 0-1-2 is all you really need.

import static java.lang.Thread.currentThread;

public class A {
  static int coordinator, timesPrinted;
  static final int numThreads = 3, timesToPrint = 300;
  public static void main(String[] args) {
    for (int i = 0; i < numThreads; i++) {
      final int myId = i;
      new Thread(new Runnable() { public void run() {
        while (true) synchronized (A.class) {
          if (coordinator%numThreads == myId) {
            System.out.println(myId+1);
            coordinator++;
            if (timesPrinted++ > timesToPrint) currentThread().interrupt();
            A.class.notifyAll();
          }
          try {A.class.wait();} catch (InterruptedException e) {break;}
        }
      }}).start();
    }
  }
}
Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • Thank you @Marko Topolnik for your reply. It was not just about the printing the number. Try to see the question in different perspective.Just for scenario it's like one thread output will be the input for the next thread. – Pradeep Kr Kaushal Jan 14 '14 at 15:57
  • Sure, I didn't think it was just about numbers---but whenever you have such an ordering constraint on threads, then it makes no sense to have the threads in the first place. You need one thread which executes the tasks in order. Whether or not you need even that one thread in addition to some "main" thread is still open---if you really do, then Jakub's solution is the right choice. If not, then you don't even need an executor service involved. – Marko Topolnik Jan 14 '14 at 16:05