猿问

Java wait() notify()循环打印A和B

public class Test {

    

    public static Object object = new Object();

    public static boolean printA = true;

    

    public static void main(String[] args) {

        ThreadA threadA = new ThreadA();

        threadA.start();

        

        ThreadB threadB = new ThreadB();

        threadB.start();

    }

}

 

class ThreadA extends Thread {

    

    @Override

    public void run() {

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

            synchronized (Test.object) {

                if(!Test.printA) {

                    try {

                        Test.object.wait();

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                } else {

                    System.out.println("A");

                    Test.printA = false;

                    Test.object.notify();

                }

            }

        }

    }

}


class ThreadB extends Thread {

    

    @Override

    public void run() {

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

            synchronized (Test.object) {

                if(Test.printA) {

                    try {

                        Test.object.wait();

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                } else {

                    System.out.println("B");

                    Test.printA = true;

                    Test.object.notify();

                }

            }

        }

    }

}

运行以上代码,为什么会一直不结束无限wait下去?


SMILET
浏览 762回答 5
5回答

慕码人2483693

实际上线程中不应该有else,把else注释掉就正确了。 如果加上else后,该线程会在wait后不再notify,导致另一个线程无限wait。public class Test {&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; public static Object object = new Object();&nbsp; &nbsp; public static boolean printA = true;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; ThreadA threadA = new ThreadA();&nbsp; &nbsp; &nbsp; &nbsp; threadA.start();&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; ThreadB threadB = new ThreadB();&nbsp; &nbsp; &nbsp; &nbsp; threadB.start();&nbsp; &nbsp; }}&nbsp;class ThreadA extends Thread {&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; @Override&nbsp; &nbsp; public void run() {&nbsp; &nbsp; &nbsp; &nbsp; for(int i = 0; i < 10; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; synchronized (Test.object) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(!Test.printA) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Test.object.wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }/* else {*/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("A");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Test.printA = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Test.object.notify();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /*}*/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}class ThreadB extends Thread {&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; @Override&nbsp; &nbsp; public void run() {&nbsp; &nbsp; &nbsp; &nbsp; for(int i = 0; i < 10; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; synchronized (Test.object) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(Test.printA) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Test.object.wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }/* else { */&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("B");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Test.printA = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Test.object.notify();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /*}*/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}

吃鸡游戏

这个和生产者消费者的问题很像。你题目中无限wait下去唯一的情况是:当ThreadA或ThreadB有一方已执行完,未执行完的线程wait之后,另一线程并不能唤醒它,因为那个线程已跑完了。

慕侠2389804

A线程先跑,如果B还没有wait的时候,A已经notify了,这时这个notify就没有效果,等B开始wait了,A的notify已经跑完了,根本永远得不到通知,你这么写逻辑是有问题的

慕村9548890

很明显ThreadB先wait,但代码却ThreadA先调用.... 只要让ThreadB先执行就可以了ThreadB threadB = new ThreadB();threadB.start();&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;Thread.sleep(10);&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;ThreadA threadA = new ThreadA();threadA.start();注意:两个Thread同时执行,java并不能能保证先调用的Thread先执行。
随时随地看视频慕课网APP

相关分类

Java
我要回答