[英]Multithreading in Java
我是编程新手,所以我决定编写一个简单的多线程程序。 它显示了餐厅的工作。客户点菜,侍者端菜,厨师做饭。 但是我有一个问题,我认为这是死锁的情况,因为当我运行它时,它会显示“ ordering”(排序),而没有其他内容。 我不明白怎么了。 请帮忙。谢谢。
Restaurant.java
public class Restaurant implements Runnable{
Client cl=new Client();
Chef ch=new Chef();
Waiter w=new Waiter();
public synchronized void makeOrder() throws InterruptedException{
notifyAll();
cl.makeOrder();
wait();
}
public synchronized void makeServing() throws InterruptedException{
notifyAll();
wait();
}
public synchronized void makeFood() throws InterruptedException{
notifyAll();
ch.makeFood();
Thread.sleep(1000);
wait();
}
@Override
public void run() {
try {
for(int i=0;i<10;i++){
makeOrder();
makeServing();
makeFood();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端.java
public class Client{
public void makeOrder(){
System.out.println("Ordering"+Thread.currentThread().getId());
}
服务员
public class Waiter {
public void makeServe() {
System.out.println("Serving order"+Thread.currentThread().getId());
}
Chef.java
public class Chef {
public void makeFood(){
System.out.println("Making food "+Thread.currentThread().getId());
}
Main.java
public class Main {
public static void main(String[] args) {
Restaurant r=new Restaurant();
Thread t=new Thread(r);
t.start();
}
}
当您调用makeOrder();
在餐厅线程中,它将等待()。 然后什么也不会发生。 问题是,您只有一个线程,该线程无法通知自己。 我认为您想要做的就是将您的客户,服务员和厨师变成线程。 然后一个接一个地启动它们,然后服务员必须等到客户下达订单,而厨师必须等到服务员下达订单...
如果您搜索“ java生产者消费者示例”,则可能会找到一些有用的示例。
如果您想通过对餐厅建模来学习多线程,请尝试此模型;
参加Restaurant
课程。 请注意,本店概不Runnable
,因为餐厅本身并不做任何事情(它里面的人做)。 相反,餐厅包含其他实际上“做东西”的类。
参加一个Waiter
班。 服务员应定期(例如,每1分钟)检查一下餐厅,以等待顾客点餐。 如果找到要订购的客户,它将创建一个订单并将其添加到订单队列中。 您的餐厅可以包含多个Waiter
实例。
参加Chef
课程。 厨师订阅了服务员写入的订单队列。 每当创建新订单时,厨师都会烹饪该订单(这需要一些时间,例如2分钟),然后提醒任何免费的服务生。 然后服务员将食物提供给顾客。 您的餐厅可以容纳多个Chef
实例。
有一个Customer
类。 顾客应随机参观餐厅。 他们等待服务员点菜,等待食物到达,吃掉食物然后离开。 为了获得奖励积分,请为您的餐厅提供容纳能力,并把顾客拒之门外/让他们等满时就等。
本示例中使用的概念
您正在滥用等待/通知机制。 :-)这是真正的问题。
在Java中,wait / notify用于实现条件变量 ,它允许线程等待满足“条件”。 另一个线程还可以通知任何等待线程说“可以”满足条件,并重新检查条件。
这是一个简单的例子:
public class Exchanger<T> {
private T item;
public synchronized T poll() {
while (item == null)
wait();
T result = item;
item = null;
notifyAll();
return result;
}
public synchronized void offer(T value) {
if (value == null)
throw new NullPointerException();
while (item != null)
wait();
item = value;
notifyAll();
}
}
这里有两个条件(用一个条件变量包装,通常不是很干净,但是):
基本上,每当调用poll
或offer
,它都会阻塞,直到另一个线程分别执行offer
或poll
为止。 为了测试何时阻止,它会在while
循环内进行相关检查。
如果您使用的是如下所示的main方法,那么您的代码将起作用(给出输出):
public static void main(String[] args) {
Restaurant r = new Restaurant();
new Thread(r).start();
new Thread(r).start();
new Thread(r).start();
}
该程序将运行一段时间,然后将暂停,因为它将等待更多的“请求”,因此不会陷入僵局。 死锁需要两个不同的锁,而您的代码中只有一个。
请注意,您仍然可能存在逻辑上的“缺陷/错误”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.