@Override
  public void run() {
    try {
      while (!Thread.interrupted()) {
        synchronized (this) {
          while (restaurant.meal != null) {
            wait();
          }
        }

        if (++count == 11) {
          System.out.println("菜上齐了");
          // 这块只是向 chef 和 waiter 发送一个 interrupt 信号
          // 但是因为 synchronized 和 IO 是不能被中断的,所以这里会通过可中断的
          // sleep()抛出 InterruptedException。
          // 而 waiter 只能通过 while(Thread.interrupted())抛出的 InterruptedException返回

          // 而且我们会发现,多做了一个菜!本来做了10个就够了。11个本意想关闭程序,但是因为
          // synchronized 无法中断,只好又做了一个菜(厨师也饿了)。但是因为服务员在 wait(),可以被中断
          // 所以做好的菜没有被服务员上去。。。。
          restaurant.exec.shutdownNow();
        }

        System.out.print("做菜ing...");
        synchronized (restaurant.waiter) {
          restaurant.meal = new Meal(count);
          restaurant.waiter.notifyAll();
        }

        TimeUnit.MILLISECONDS.sleep(100);
      }
    } catch (InterruptedException e) {
      System.out.println("chef interrupted");
    }
  }
 @Override
 public void run() {
   try {
     while (!Thread.interrupted()) {
       synchronized (this) {
         while (restaurant.meal == null) {
           wait();
         }
       }
       System.out.println("Waiter got " + restaurant.meal);
       // 为什么要选择 chef 作为同步控制块的锁呢?
       // 废话,想通知 chef,肯定要调用 chef.notifyAll()。因为 notifyAll()必须在
       // 同步控制块中调用,而且释放的是 chef 的锁,肯定需要先获取 chef 的锁了。。。
       synchronized (restaurant.chef) {
         restaurant.meal = null;
         restaurant.chef.notifyAll(); // 准备下一道菜
       }
     }
   } catch (InterruptedException e) {
     System.out.println("Waiter interrupted");
   }
 }