Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
600 views
in Technique[技术] by (71.8m points)

multithreading - 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());
        }

    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...