饭店仿真,适合初学者熟悉多线程
package default; import java.io.IOException; import java.util.ArrayList; import java.util.Random; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.TimeUnit; class Course { private static Random rand = new Random(); private static int foodNum = 10; public static Food[] foods = new Food[10]; static { for (int i = 0; i < foodNum; i++) { foods[i] = new Food("food" + i); } } public static Food randomSelection() { return foods[rand.nextInt(foodNum)]; } } class Food { String foodName; public Food(String name) { foodName = name; } @Override public String toString() { return "food:" + foodName + " "; } } //订单类,记录点菜的Customer,点的Food,服务员是谁,由顾客产生 class Order { private Food food; private Customer customer; private WaitPerson waitPerson; public Order(Food food, Customer customer, WaitPerson waitPerson) { this.food = food; this.customer = customer; this.waitPerson = waitPerson; } public Food getFood() { return food; } public void setFood(Food food) { this.food = food; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } public WaitPerson getWaitPerson() { return waitPerson; } public void setWaitPerson(WaitPerson waitPerson) { this.waitPerson = waitPerson; } @Override public String toString() { return customer + "点了" + food + "由服务员" + waitPerson + "服务"; } } //用来装食物的碟子,被waitPerson所使用 由Chef产生,放入WaitPerson的队列中 class Plate { public Plate(Food food, Order order) { this.food = food; this.order = order; } private Food food; private Order order; public Food getFood() { return food; } public void setFood(Food food) { this.food = food; } public Order getOrder() { return order; } public void setOrder(Order order) { this.order = order; } } //顾客类,由餐厅产生,点餐,等餐,吃饭,走人 class Customer implements Runnable { private static Random rand = new Random(); private static int counter = 0; private final int id = counter++; // 从中取出食物吃 private final SynchronousQueue<Plate> plate; //Customer 最关心的是waitPerson,因为他下单或者桌子上的食物都是由WaitPerson服务的 private final WaitPerson waitPerson; public Customer(WaitPerson waitPerson) { plate = new SynchronousQueue<>(); this.waitPerson = waitPerson; } public void putPlate(Plate p) throws InterruptedException { this.plate.put(p); } public void placeOrder() throws InterruptedException { //模拟下单时间 TimeUnit.MILLISECONDS.sleep(100 + rand.nextInt(300)); Order order = new Order(Course.randomSelection(), this, waitPerson); System.out.println(order); waitPerson.plateOrder(order);; } @Override public void run() { try { do { placeOrder(); Plate p = this.plate.take(); //模拟吃饭的时间 TimeUnit.MILLISECONDS.sleep(200 + rand.nextInt(1000)); System.out.println(this + "eating " + p.getFood()); //有1/2的机会还想再吃一个,没吃饱 } while (rand.nextBoolean()); } catch (InterruptedException e) { System.out.println(this + "Interrupted!"); } System.out.println(this + "leaving off!"); } @Override public String toString() { return "Customer:" + id + " "; } } //向BlockingQueue这种东西是不应该暴露给别的类的,最好只是暴露接口给别人 //服务员,从Chef手中拿食物给对应的Customer,每一个waitPerson都维护着自己的一个盘子队列 //不停的取食物然后送给对应的customer class WaitPerson implements Runnable { private static int counter = 0; private final int id = counter++; private final BlockingQueue<Plate> plates; private final Restaurant restaurant; public WaitPerson(Restaurant restaurant) { this.plates = new LinkedBlockingQueue<>(); this.restaurant = restaurant; } public void plateOrder(Order order){ restaurant.addOrder(order); } //call by Chef public void putPlate(Plate plate) throws InterruptedException { this.plates.put(plate); } @Override public void run() { try { while (!Thread.interrupted()) { Plate plate = plates.take(); //在盘子取出订单 Order order = plate.getOrder(); //模拟移动到顾客旁边的时间 TimeUnit.MILLISECONDS.sleep(300); //在订单中找到Customer Customer customer = order.getCustomer(); //然后把食物给Plate给Customer customer.putPlate(plate); } } catch (InterruptedException e) { System.out.println("WaitPeron Interrupted"); } } @Override public String toString() { return "WaitPerson:" + id + " "; } } //厨师类, 接收order产生食物并且装plate,然后给WaitPerson class Chef implements Runnable { private static Random rand = new Random(); private static int counter = 0; private final int id = counter++; private final Restaurant restaurant; public Chef(Restaurant restaurant) { this.restaurant = restaurant; } @Override public void run() { try { while (!Thread.interrupted()) { Order order = this.restaurant.takeOrder(); Food food = order.getFood(); //模拟做菜的时间 TimeUnit.MILLISECONDS.sleep(rand.nextInt(800) + 100); Plate plate = new Plate(food, order); order.getWaitPerson().putPlate(plate); } } catch (InterruptedException e) { System.out.println(this + "Interrupted!"); } System.out.println(this + "off duty!"); } @Override public String toString() { return "Chef:" + id + " "; } } //餐厅类,负责协调管理WaitPerson,Chef,Customer队伍, 并且让他们都run起来 //同时还自动每隔一段时间产生一名Customer class Restaurant implements Runnable { private ArrayList<WaitPerson> waitPersons = new ArrayList<>(); private ArrayList<Chef> chefs = new ArrayList<>(); private BlockingQueue<Order> orders = new LinkedBlockingQueue<>(); private ExecutorService exec; private static Random rand = new Random(); private int nWaitPerson; //让WaitPerson Chef都工作起来 public Restaurant(int nWaitPersons, int nChefs, ExecutorService exec) { this.exec = exec; this.nWaitPerson = nWaitPersons; for (int i = 0; i < nWaitPersons; i++) { WaitPerson waitPerson = new WaitPerson(this); waitPersons.add(waitPerson); exec.execute(waitPerson); } for (int i = 0; i < nChefs; i++) { Chef chef = new Chef(this); chefs.add(chef); exec.execute(chef); } } //接单 public void addOrder(Order order) { orders.add(order); } //厨师取单 public Order takeOrder() throws InterruptedException { return this.orders.take(); } @Override public void run() { try { while (!Thread.interrupted()) { Customer customer = new Customer( this.waitPersons.get(rand.nextInt(nWaitPerson))); TimeUnit.MILLISECONDS.sleep(300 + rand.nextInt(400)); exec.execute(customer); } } catch (InterruptedException e) { System.out.println("Restaurant is Interrupted!"); } System.out.println("Restaurant is closing!"); } } public class RestaurantWithQueues { public static void main(String[] args) throws IOException { ExecutorService exec = Executors.newCachedThreadPool(); Restaurant restaurant = new Restaurant(10, 10, exec); exec.execute(restaurant); System.out.println("Press Enter to quit!"); System.in.read(); exec.shutdownNow(); } }