0

how to run threads after other threads finished, let say i have 3 java class (Cls1 and Cls2 implements runnable, and I use sleep to know which statements are run first), this is my code :

public class Master {
    @SuppressWarnings("unused")
    public static void main(String[] args) {
        //loop1
        for(int i=1; i<=2; i++) {
            Cls1 c1 = new Cls1();
        }

        //Here i want to wait until the thread loop1 is finished, what to do?

        //loop2
        for(int j=1; j<=2; j++) {
            Cls2 c2 = new Cls2();
        }
    }
}

public class Cls1 implements Runnable{
    Thread myThread;
    Cls1() {
        myThread = new Thread(this, "");
        myThread.start();       
    }

    @Override
    public void run() {
        System.out.println("hello1");
        TimeUnit.SECONDS.sleep(3);
        System.out.println("hello2");
    }
}

public class Cls2 implements Runnable{
    Thread myThread;
    Cls2() {
        myThread = new Thread(this, "");
        myThread.start();
    }

    @Override
    public void run() {
        System.out.println("hello3");
        TimeUnit.SECONDS.sleep(3);
        System.out.println("hello4");
    }
}

And this is output my code : hello1 hello1 hello3 hello3 hello2 hello2 hello4 hello4

And this is the output I expect: hello1 hello1 hello2 hello2 hello3 hello3 hello4 hello4

What should I do ?

frianH
  • 7,295
  • 6
  • 20
  • 45
  • 2
    use `Executor executor = Executors.newSingleThreadExecutor();` for running the threads one after another – Rishal Apr 06 '18 at 09:35
  • 4
    Don't use thread if you want serial execution of program. – Sandesh Gupta Apr 06 '18 at 09:36
  • 1
    Possible duplicate of [Java Wait for thread to finish](https://stackoverflow.com/questions/4691533/java-wait-for-thread-to-finish) – vincrichaud Apr 06 '18 at 09:39
  • @SandeshGupta that's not Serial execution since there are two Cls1 threads running in parallel. But he need to wait for all Cls1 to finish before launching Cls2. – vincrichaud Apr 06 '18 at 09:40
  • @vincrichaud yes right, that's my point. but if i used "join", it will make my cls1 run serial – frianH Apr 06 '18 at 09:54

3 Answers3

3

If you want to wait for the thread to finish, call the join method.

vincrichaud
  • 2,218
  • 17
  • 34
  • Hi @vincrichaud, if i use "join" it will make my cls1 run serial, i get output : hello1 hello2 hello1 hello2 hello3 hello4 hello3 hello4 – frianH Apr 06 '18 at 10:04
  • @Frian No it wont. `join` does not affect the thread. Your result seems to be serial cause it is to small (so you don't have time to see the paralelllism appear). Try with for-loop inside your thread that prints 10000 times "1" in the first instance and "2" in the second. You will see that the 1s and 2s are interleaved. – vincrichaud Apr 06 '18 at 11:02
  • @Frian You will maybe face a problem cause in your code, the cls1 instance is in the for-loop scope. So you can't access it from outside the loop to call join. Also It's supposed to destroy c1 instance at the end of the loop. So maybe it causes your code to be serial – vincrichaud Apr 06 '18 at 11:04
  • i've your suggest and you right cls1 run throught parallel, but the cls2 runs before cls1 is completely finished, i've add "join" in cls1 and cls2 before "start" in my code :) – frianH Apr 06 '18 at 11:25
  • @Frian look what Maurice Perry answered. I think your problem is because of your way to declare and instantiate c1. You loose the reference to the first cls1 instance cause you put a second instance in the same variable. So you wait for only one to join and not for both – vincrichaud Apr 06 '18 at 11:30
3

You could try something like that:

@SuppressWarnings("unused")
public static void main(String[] args) {
    Thread threads[] = new Thread[2];
    //loop1
    for(int i=1; i<=2; i++) {
        threads[i-1] = new Cls1();
    }

    for (Thread thread: threads) {
        thread.join();
    }

    //loop2
    for(int j=1; j<=2; j++) {
        Cls2 c2 = new Cls2();
    }
}

UPDATE: Make Cls1 a subclass of Thread:

public class Cls1 extends Thread {
    Cls1() {
        start();       
    }

    @Override
    public void run() {
        System.out.println("hello1");
        TimeUnit.SECONDS.sleep(3);
        System.out.println("hello2");
    }
}
Maurice Perry
  • 9,261
  • 2
  • 12
  • 24
0

To run thread one after another, it needs to be synchronized. wait, notify and notifyAll ..all of these can be used. If you don't synchronize it, then it doesn't guarantee the order of output what you desire to be produced.

So for this we have to take one variable "flag" and and synchronize threads one by one as below:

If value of flag=1, then it is class A's turn to print.

If value of flag=2, then it is class B's turn to print. If value of flag=3, then it is class C's turn to print.

Ashit
  • 59
  • 6