代码
package com.example.KFC;  
public class Cooker extends Thread {  public void run() {  while (true) {  synchronized (Desk.lock) {  if (Desk.maxCount == 0) {  break;  } else {  if (!Desk.flag) {  System.out.println("Cooker makes a hamburger");  Desk.flag = true;  Desk.lock.notifyAll();  } else {  try {  Desk.lock.wait();  } catch (InterruptedException e) {  throw new RuntimeException(e);  }  }  }  }  }  }  
}
package com.example.KFC;  
public class Foodie extends Thread {  public void run() {  while (true) {  synchronized (Desk.lock) {  if (Desk.maxCount == 0) {  System.out.println("Foodie is out of food");  break;  } else {  if (Desk.flag) {  Desk.maxCount--;  System.out.println("Foodie eats a hamburger and have " + Desk.maxCount + " hamburger to eat left");  Desk.flag = false;  Desk.lock.notifyAll();  } else {  try {  Desk.lock.wait();  } catch (InterruptedException e) {  throw new RuntimeException(e);  }  }  }  }  }  }  
}
package com.example.KFC;  
public class Desk {  public static boolean flag = false;  public static int maxCount = 10;  static Object lock = new Object();  
}
package com.example.KFC;  
public class Demo {  public static void main(String[] args) {  Foodie f = new Foodie();  Cooker c = new Cooker();  f.start();  c.start();  }  
}
背景介绍
这四个程序是一个简单的生产者消费者模型的实现,用于模拟厨师(生产者)制作汉堡,食客(消费者)吃汉堡的过程。
 Desk.java:这是一个共享资源类,包含了一个标志位flag,一个最大计数器maxCount和一个锁对象lock。flag用于标记是否有汉堡可供食客吃,maxCount用于记录还剩下多少汉堡,lock用于同步厨师和食客的行为。
 Cooker.java:这是厨师类,继承了Thread类。在其run方法中,厨师会不断地制作汉堡,直到maxCount为0。如果flag为false,表示没有汉堡,厨师就会制作一个汉堡,并将flag设为true,然后唤醒所有在lock上等待的线程(即食客)。如果flag为true,表示有汉堡,厨师就会在lock上等待。
 Foodie.java:这是食客类,也继承了Thread类。在其run方法中,食客会不断地吃汉堡,直到maxCount为0。如果flag为true,表示有汉堡,食客就会吃掉一个汉堡,并将flag设为false,然后唤醒所有在lock上等待的线程(即厨师)。如果flag为false,表示没有汉堡,食客就会在lock上等待。
 Demo.java:这是主程序类,创建了一个厨师线程和一个食客线程,并启动它们。
 这四个程序共同模拟了一个生产者消费者问题的解决方案,通过wait和notifyAll方法以及同步块来保证厨师和食客的行为的同步性,避免了资源的浪费和冲突。
流程解读

 一个“锁”上的多个线程在同一时间只能有一个处于运行态;
在本案例中,吃货和厨师在start后进入就绪态,随后吃货进入运行态,厨师在就绪态“排队”,随后吃货在run中notifyAll,随后他通过wait进入等待态,在就绪态准备的厨师进入运行态,执行厨师进程的run,在对Desk执行完方法后notiFyAll唤醒吃货使其进入就绪态排队,随后厨师通过wait进入等待态,在就绪态准备的吃货进入运行态,如此周而复始,一直到共享数据结束。