繁体   English   中英

Java多线程

[英]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生产者消费者示例”,则可能会找到一些有用的示例。

如果您想通过对餐厅建模来学习多线程,请尝试此模型;

  1. 参加Restaurant课程。 请注意,本店概不Runnable ,因为餐厅本身并不做任何事情(它里面的人做)。 相反,餐厅包含其他实际上“做东西”的类。

  2. 参加一个Waiter班。 服务员应定期(例如,每1分钟)检查一下餐厅,以等待顾客点餐。 如果找到要订购的客户,它将创建一个订单并将其添加到订单队列中。 您的餐厅可以包含多个Waiter实例。

  3. 参加Chef课程。 厨师订阅了服务员写入的订单队列。 每当创建新订单时,厨师都会烹饪该订单(这需要一些时间,例如2分钟),然后提醒任何免费的服务生。 然后服务员将食物提供给顾客。 您的餐厅可以容纳多个Chef实例。

  4. 有一个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();
    }
}

这里有两个条件(用一个条件变量包装,通常不是很干净,但是):

  • 物品栏位为空
  • 物品栏位不为空

基本上,每当调用polloffer ,它都会阻塞,直到另一个线程分别执行offerpoll为止。 为了测试何时阻止,它会在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM