请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

代码中 notifyAll() 的位置能否这样写?

我把 notifyAll() 的位置改动了一下,发现也可以运行。但是不知道这样写是否会出现隐藏的问题,请老师解答。

消费者:

public class Consumer extends Thread{
    @Override
    public void run() {
        while (true) {
            synchronized (Desk.lock) {
                // true 代表桌上有食物
                if (Desk.flag) {
                    System.out.println("消费者正在取餐");
                    Desk.flag = false;
                    //Desk.lock.notifyAll();
                } else {
                    // false 代表桌上没有食物,消费者需要等待
                    try {
	                    // 把 notifyAll() 写在这里
                        Desk.lock.notifyAll();
                        Desk.lock.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
}

生产者:

public class Producer extends Thread{
    @Override
    public void run() {
        while (true) {
            synchronized (Desk.lock) {
                if (Desk.flag) {
                    try {
	                    // notifyAll() 写在这里
                        Desk.lock.notifyAll();
                        Desk.lock.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    System.out.println("通知消费者吃饭");
                    Desk.flag = true;
//                    Desk.lock.notifyAll();
                }
            }
        }
    }
}

正在回答 回答被采纳积分+3

1回答

Alfred_li 2023-10-19 19:22:20

你的代码是没问题的

public class Producer extends Thread{
    @Override
    public void run() {
        while (true){
            synchronized (Desk.lock){
                if(Desk.flag){
                    try {
	                    // notifyAll() 写在这里
                        Desk.lock.notifyAll();
                        Desk.lock.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }else{
                    System.out.println("厨师正在补充食物");
                    Desk.flag = true;
                }
            }
        }
    }
}
public class Consumer extends Thread{
    @Override
    public void run() {
        while (true){
            synchronized (Desk.lock){
                if(Desk.flag){
                    System.out.println("顾客取走食物");
                    Desk.flag = false;
                }else{
                   // false 代表桌上没有食物,消费者需要等待
                    try {
	                    // 把 notifyAll() 写在这里
                        Desk.lock.notifyAll();
                        Desk.lock.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
}

消费者notifyAll后会通知厨师线程,然后调用wait()方法等待厨师唤醒自己
厨师线程notifyAll后通知消费者线程,然后调用wait()方法等待消费者唤醒自己


0 回复 有任何疑惑可以回复我~
  • 提问者 Wab77 #1
    老师好,我对这句话不理解:「而实际上notifyAll方法后边的wait是没有机会被执行的,因为调用notifyAll,是要唤醒其他线程,当前线程就不在执行了」。
    
    我的理解是,A 线程唤醒 B 线程后,A 线程应该会继续执行后面的代码,直到 A 线程释放了 lock 锁之后,B 线程才能继续执行 wait 之后的代码。
    回复 有任何疑惑可以回复我~ 2023-10-19 20:27:03
  • Alfred_li 回复 提问者 Wab77 #2
    你的理解是对的,notifyAll()方法会在一个临界区内被调用,而在调用之后,当前线程会继续执行临界区内的剩余代码,然后释放锁,你之前的代码是没问题的
    回复 有任何疑惑可以回复我~ 2023-10-19 23:18:22
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信