多个顾客、多个服务生、多个厨师,服务生需要同时检查顾客点菜请求、厨师完成通知,如何处理?

解决方案 »

  1.   

    你想让人再给你把这个copy一份?
      

  2.   

    在没有加入顾客的情况下,多个服务生、多个厨师由服务生自己下订单,在餐厅加入订餐LIST、准备就绪Map<Waiter,Order>后已经解决。
    但是加入顾客以后,Waiter除了需要检查准备就绪Map以外还需要检查顾客订餐LIST,这该怎么处理呢?
      

  3.   


    订餐LIST 这个是顾客的行为啊,顾客就是一个线程。
      

  4.   


    class Order {
    private static int i = 0;
    private int count = i++;
    private WaitPerson waiter;
    public Order(WaitPerson w) {
    this.waiter = w;
    if(count == 10){
    System.out.println("Out of food, closing");
    System.exit(0);
    }
    }
    public WaitPerson getWaiter(){
    return this.waiter;
    }
    public String toString() { return "Order" + count; }
    }
    class Custom extends Thread {
    int num;
    Restaurant restaurant;
    WaitPerson waitPerson;
    Custom(int num, Restaurant r, WaitPerson w){
    this.num = num;
    this.restaurant = r;
    this.waitPerson = w;
    start();

    }
    public void run(){
    try {
    while(true){
    sleep(1000);
    synchronized (restaurant.getOrderList()) {
    Order order = new Order(this.waitPerson);
    restaurant.newOrder(order);
    restaurant.getOrderList().notifyAll();
    System.out.println("No." + this.num + " custom order up " + order);
    }
    }
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    public String toString() {return "";}
    }
    class WaitPerson extends Thread {
    private Restaurant restaurant;
    private String name;
    public WaitPerson(String name, Restaurant r){
    restaurant = r;
    this.name = name;
    start();
    }
    public void run(){
    while(true){
    try {
    synchronized (restaurant.getReadyList()) {
    while(restaurant.getReady(this) == null){
    synchronized (this) {
    this.wait();
    }
    }
    Order removed = restaurant.removeReady(this);
    System.out.println(this.name + " got " + removed);
    }
    } catch (InterruptedException e1) {
    e1.printStackTrace();
    }
    }
    }
    }class Chef extends Thread{
    private String name;
    private Restaurant restaurant;
    public Chef(String name,Restaurant r){
    this.name = name;
    restaurant = r;
    start();
    }
    public void run(){
    while(true){
    synchronized (restaurant.getOrderList()) {
    while(restaurant.getFirstOrder() == null){
    try {
    restaurant.getOrderList().wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    try {
    sleep(400);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }//模拟做菜4秒
    Order o = restaurant.getFirstOrder();
    restaurant.newReady(o.getWaiter(), o);
    System.out.println(this.name + " done order " + o);
    synchronized (o.getWaiter()) {
    o.getWaiter().notify();
    }
    }
    }
    }
    }public class Restaurant {
    private List<Order> orderList = new ArrayList<Order>();
    private Map<WaitPerson,List<Order>> readyMap = new HashMap<WaitPerson,List<Order>>();
    public List<Order> getOrderList(){
    return orderList;
    }
    public Map<WaitPerson,List<Order>> getReadyList(){
    return readyMap;
    }
    public void newOrder(Order o){
    orderList.add(o);
    }
    public Order getFirstOrder(){
    return (orderList.size() == 0) ? null : orderList.get(0);
    }
    public Order newReady(WaitPerson w,Order o){
    if(readyMap.get(w) != null){
    readyMap.get(w).add(o);
    }else{
    List<Order> readyOrderlist = new ArrayList<Order>();
    readyOrderlist.add(o);
    readyMap.put(w, readyOrderlist);
    }
    orderList.remove(0);
    return o;
    }
    public Order getReady(WaitPerson w){
    List<Order> olist = new ArrayList<Order>();
    olist = readyMap.get(w);
    if(olist != null){
    return (olist.size() == 0) ? null : olist.get(0);
    }else{
    return null;
    }
    }
    public Order removeReady(WaitPerson w){
    return readyMap.get(w).remove(0);
    }
    public static void main(String[] args){
    Restaurant restaurant = new Restaurant();
    WaitPerson waitPerson1 = new WaitPerson("aaa", restaurant);
    WaitPerson waitPerson2 = new WaitPerson("bbb", restaurant);
    WaitPerson waitPerson3 = new WaitPerson("ccc", restaurant);
    WaitPerson waitPerson4 = new WaitPerson("ddd", restaurant);
    Custom c1 = new Custom(1,restaurant,waitPerson4);
    Custom c2 = new Custom(2,restaurant,waitPerson3);
    Custom c3 = new Custom(3,restaurant,waitPerson2);
    Custom c4 = new Custom(4,restaurant,waitPerson1);
    Custom c5 = new Custom(5,restaurant,waitPerson4);
    Custom c6 = new Custom(6,restaurant,waitPerson3);
    Chef chef1 = new Chef("Jimmy",restaurant);
    Chef chef2 = new Chef("Manny",restaurant);
    }
    }如果是这样一种业务设定,一个顾客进店后会被指定一个服务生,然后每次订餐都会找这个服务生,那么上面的代码就可以工作。
      

  5.   

    那这个设定下,服务生需要同时等待顾客点餐、厨师通知送餐。
    一个线程中怎么会有两个WAIT呢?
      

  6.   

    确实没法同时Wait两个事件,所以要研究下你Wait的是什么,其实服务员等待的应该是个呼叫。在你引入顾客后,这个模型其实变得比较复杂:
    厨师--服务员:厨师提供做好的菜让服务员送餐;
    服务员--顾客:顾客点菜后要服务员下单。看来还是要引入命令队列,会让这个模型显得更清晰和简单点:
    做个服务员的命令队列,厨师和顾客都向这个队列中放入自己的呼叫,放入后即等待该呼叫被处理。
    服务员则从该队列中获取任务,根据是厨师任务还是顾客任务分别进行处理,完成后唤醒厨师或顾客,然后继续从队列找下一个任务。这样做应该会更清晰些。。