running 3 threads in sequence java
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.
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(); } } }}