java - wait 和 notifyall 等待其他线程

标签 java multithreading

我正在使用线程在 Java 中处理厨师、面包和客户场景。所以基本上是厨师做面包,顾客吃,厨师做更多。最多20个,有20个时厨师停止做面包,没有剩下时顾客停止进食。但每次我使用 notifyall 时,它都会等待四秒钟,然后顾客才能吃掉它(应该再做 3 个面包)。 这是在 Chef 类中运行的代码(实现可运行)

public void run(){
    int id = 0;
    while(true){
        if(Basket.breadList.size() == 20){
            synchronized(Basket.breadList){
                try {
                    Basket.breadList.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        Bread bread = new Bread(id);

        System.out.println("Bread " + id + " had just been made. ");
        synchronized(Basket.breadList){
            Basket.breadList.notifyAll();
            try {
                Thread.sleep(1000);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            id++;
        }


    }
}

这是客户的代码:

public void run(){
    int id;
    while(true){
        if(Basket.breadList.size() == 0){
            synchronized(Basket.breadList){
                try {
                    Basket.breadList.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        id = Basket.breadList.get(Basket.breadList.size()-1).id;
        Basket.breadList.remove(Basket.breadList.size()-1);
        System.out.println("Bread " + id + " had just been eaten. ");
        synchronized(Basket.breadList){
            Basket.breadList.notifyAll();
            try {
                Thread.sleep(4000);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }



    }

}

Controller 中的代码如下:

public static void main(String[] args) {
    Chef chef = new Chef();
    Customer customer = new Customer();
    Thread t1 = new Thread(chef);
    Thread t2 = new Thread(customer);
    t1.start();

    try {
        Thread.sleep(20);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    t2.start();

}

Basket.breadList 只是面包的数组列表。

请帮忙。非常感谢!

最佳答案

在您的客户吃完任何面包后,它总是会等待 4 秒。没有什么可以阻止这种等待(通常应该有一些 if ())。

规则:永远不要无条件地 sleep(),除非你绝对确定这是应该的。您总是 sleep() 因为没有其他事情可以完成,而且可能暂时不会。所以你需要检查是否有。

此外,notifyAll() 通常会在一些先前的操作之后立即完成,这些操作使其他线程可以处理一些事情。
规则:在容器中放入东西后立即调用 notifyAll()。

也不清楚厨师在哪个代码中以及何时将面包添加到篮子中。我假设 bread 将自身添加到自己的构造函数中——如果是这样,它就是一种反模式。保持面包简单健康,这样味道会更好。让厨师做这项工作。如果在揉面和烘烤过程中面包自己爬进篮子里,我会吓坏的。

一般来说,尽量按照现实世界中 Actor 的行为来编写代码。厨师会通知客户购物篮不为空吗?什么时候?当篮子空了,顾客会通知厨师吗?什么时候?他们中的任何一个在什么时候等待?

关于java - wait 和 notifyall 等待其他线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32546029/

相关文章:

java - Jboss 7 Jaas模块,成功登录后角色被覆盖

JavaBeans 与复杂类型一起使用

java - 如何使用 jmockit 从模拟类调用真实方法

c - 在使用 pthreads 的 C 语言中,如何让某个线程运行直到达到某个值?

c++多线程单例 - 此代码有任何问题

c++ - 竞争条件会降低代码的性能吗?

objective-c - iPad GUI 仅在触摸后更新

java - 如何在hibernate条件中使用mysql的 "use index()"子句?

java - 如何使用 Maven 的程序集插件将 Implementation-Version 值添加到 jar list ?

java - Android 多线程应用程序崩溃