running 3 threads in sequence java

 public class RunThreadsInOrder implements Runnable {

    static int numThread = 1;
    static int threadAllowedToRun = 1;
    int myThreadID;
    private static Object myLock = new Object();

    public RunThreadsInOrder() {
        this.myThreadID = numThread++;
        System.out.println("Thread ID:" + myThreadID);
    }

    @Override
    public void run() {
        synchronized (myLock) {
            while (myThreadID != threadAllowedToRun) {
                try {
                    myLock.wait();
                } catch (InterruptedException e) {

                } catch (Exception e) {}
            }
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }

            System.out.println("myThreadID is running: " + myThreadID);
            myLock.notifyAll();
            threadAllowedToRun++;
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Thread t1 = new Thread(new RunThreadsInOrder());
        Thread t2 = new Thread(new RunThreadsInOrder());
        Thread t3 = new Thread(new RunThreadsInOrder());
        Thread t4 = new Thread(new RunThreadsInOrder());
        Thread t5 = new Thread(new RunThreadsInOrder());
        Thread t6 = new Thread(new RunThreadsInOrder());
        Thread t7 = new Thread(new RunThreadsInOrder());

        t7.start();
        t6.start();
        t5.start();
        t4.start();
        t3.start();
        t2.start();
        t1.start();

    }
}

    public class Main {
        public static void main(String[] args) throws IOException{
        Thread t1 = new Thread(new A(), "1");
        Thread t2 = new Thread(new A(), "2");
        Thread t3 = new Thread(new A(), "3");

        t1.start();
        try{
            t1.join();
        }catch (Exception e){

        }
        t2.start();
        try{
            t2.join();
        }catch (Exception e){

        }
        t3.start();
        try{
            t3.join();
        }catch (Exception e){

        }


    }
}

    class A implements Runnable{
    public void run(){
        System.out.println(Thread.currentThread().getName());
    }
}

or you can use Executor Framework

public class Sequence {
    int valve = 1;
    public static void main(String[] args){
        Sequence s = new Sequence();
        ExecutorService es = Executors.newFixedThreadPool(3);

        List<Runnable> rList = new ArrayList<>();
        rList.add(new A(s));
        rList.add(new B(s));
        rList.add(new C(s));

        for(int i = 0; i < rList.size(); i++){
            es.submit(rList.get(i));
        }
        es.shutdown();

    }
}

class A implements Runnable{
    Sequence s;

    A(Sequence s){
        this.s = s;
    }

    public void run(){
        synchronized (s) {
            for (int i = 0; i < 10; i++) {
                while (s.valve != 1) {
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("A");
                s.valve = 2;
                s.notifyAll();
            }
        }
    }
}

class B implements Runnable{
    Sequence s;

    B(Sequence s){
        this.s = s;
    }

    public void run() {
        synchronized (s) {
            for (int i = 0; i < 10; i++) {
                while (s.valve != 2) {
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("B");
                s.valve = 3;
                s.notifyAll();
            }
        }
    }
}

class C implements Runnable{
    Sequence s;

    C(Sequence s){
        this.s = s;
    }

    public void run() {
        synchronized (s) {
            for(int i = 0; i < 10; i++) {
                while (s.valve != 3) {
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("C");
                s.valve = 1;
                s.notifyAll();
            }
        }
    }
}

In the first case the join for each thread causes the threads to wait for one another. In the second case a list stores the threads and executor executes them one after another creating 3 threads

Another way to do this is where only one runnable class is present and communication between thread is done via static variable in the main class and a variable in the runnable class

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Seq {
    int i = 1;
    public static void main(String[] args){
        Seq s = new Seq();
        Common c1 = new Common(s, 1);
        Common c2 = new Common(s, 2);
        Common c3 = new Common(s, 3);

        List<Runnable> l = new ArrayList<>();
        l.add(c1);
        l.add(c2);
        l.add(c3);

        ExecutorService es = Executors.newFixedThreadPool(3);
        for(int i = 0; i < 3; i++){
            es.submit(l.get(i));
        }
        es.shutdown();
    }
}

class Common implements Runnable{
    Seq s;
    int o;

    Common(Seq s, int o){
        this.s = s;
        this.o = o;
    }

    public void run(){
        synchronized (s) {
            for (int z = 0; z < 100; z++) {
                if(s.i > 3)
                    s.i = 1;
                while (s.i != o) {
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(o);
                s.i++;
                s.notifyAll();
            }
        }
    }
}

Convert those IF statements to WHILE statements to get the desired behavior:

if (notifyAllExample.status != 2){
    notifyAllExample.wait();
}

to

while (notifyAllExample.status != 2){
    notifyAllExample.wait();
}

This will ensure that if a thread is notified, it won't go out of the while loop until the status value is what it expects.

Also, mark status as volatile so that the threads won't have a local copy.