Jayesh Jayesh - 2 months ago 6
Java Question

running 3 threads in sequence java

I have 3 threads
1st printing A
2nd printing B
3rd printing C

I want to print in sequence A B C A B C A B C and so on.....

So I wrote the program below, but I am not able to achieve the same.
I am aware of the problem that when status=1 at that time say for example B1 and C1 thread are waiting and when I do notifyAll() both waiting thread wake up and depending on CPU allocation it might print B or C.

in this case I want only B to be printed after A.

what modification I need to do.

public class NotifyAllExample {

int status=1;
public static void main(String[] args) {

NotifyAllExample notifyAllExample = new NotifyAllExample();

A1 a=new A1(notifyAllExample);
B1 b=new B1(notifyAllExample);
C1 c=new C1(notifyAllExample);

a.start();
b.start();
c.start();
}
}

class A1 extends Thread{
NotifyAllExample notifyAllExample;

A1(NotifyAllExample notifyAllExample){
this.notifyAllExample = notifyAllExample;
}

@Override
public void run() {

try{
synchronized (notifyAllExample) {

for (int i = 0; i < 100; i++) {

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

System.out.print("A ");
notifyAllExample.status = 2;
notifyAllExample.notifyAll();
}

}
}catch (Exception e) {
System.out.println("Exception 1 :"+e.getMessage());
}

}

}

class B1 extends Thread{

NotifyAllExample notifyAllExample;

B1(NotifyAllExample notifyAllExample){
this.notifyAllExample = notifyAllExample;
}

@Override
public void run() {

try{
synchronized (notifyAllExample) {

for (int i = 0; i < 100; i++) {

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

System.out.print("B ");
notifyAllExample.status = 3;
notifyAllExample.notifyAll();
}

}
}catch (Exception e) {
System.out.println("Exception 2 :"+e.getMessage());
}

}
}


class C1 extends Thread{

NotifyAllExample notifyAllExample;

C1(NotifyAllExample notifyAllExample){
this.notifyAllExample = notifyAllExample;
}

@Override
public void run() {

try{
synchronized (notifyAllExample) {

for (int i = 0; i < 100; i++) {

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

System.out.print("C ");
notifyAllExample.status = 1;
notifyAllExample.notifyAll();
}

}
}catch (Exception e) {
System.out.println("Exception 3 :"+e.getMessage());
}

}
}

Answer

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.

Comments