我正在使用线程在 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/