thinking in java 多线程 顾客、服务生、厨师的例子 多个顾客、多个服务生、多个厨师,服务生需要同时检查顾客点菜请求、厨师完成通知,如何处理? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你想让人再给你把这个copy一份? 在没有加入顾客的情况下,多个服务生、多个厨师由服务生自己下订单,在餐厅加入订餐LIST、准备就绪Map<Waiter,Order>后已经解决。但是加入顾客以后,Waiter除了需要检查准备就绪Map以外还需要检查顾客订餐LIST,这该怎么处理呢? 订餐LIST 这个是顾客的行为啊,顾客就是一个线程。 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); }}如果是这样一种业务设定,一个顾客进店后会被指定一个服务生,然后每次订餐都会找这个服务生,那么上面的代码就可以工作。 那这个设定下,服务生需要同时等待顾客点餐、厨师通知送餐。一个线程中怎么会有两个WAIT呢? 确实没法同时Wait两个事件,所以要研究下你Wait的是什么,其实服务员等待的应该是个呼叫。在你引入顾客后,这个模型其实变得比较复杂:厨师--服务员:厨师提供做好的菜让服务员送餐;服务员--顾客:顾客点菜后要服务员下单。看来还是要引入命令队列,会让这个模型显得更清晰和简单点:做个服务员的命令队列,厨师和顾客都向这个队列中放入自己的呼叫,放入后即等待该呼叫被处理。服务员则从该队列中获取任务,根据是厨师任务还是顾客任务分别进行处理,完成后唤醒厨师或顾客,然后继续从队列找下一个任务。这样做应该会更清晰些。。 请各位达人分析一下服务器配置,谢谢 List删除符合条件项 jsp页面中分页数据保存 谁不喜欢ssh框架过来支持一个 hibernate的二级缓存怎么用啊 JSP页面控制的问题! 问几个bean问题 SPRING MVC问题 weblogic环境下找不到jspsmartfile类 请教大家一个莫名其妙的问题 看了二天Struts2,自我感觉跟Servlet JSP连接好紧密喔。你们说是不是呢?... ip字符串排序
但是加入顾客以后,Waiter除了需要检查准备就绪Map以外还需要检查顾客订餐LIST,这该怎么处理呢?
订餐LIST 这个是顾客的行为啊,顾客就是一个线程。
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);
}
}如果是这样一种业务设定,一个顾客进店后会被指定一个服务生,然后每次订餐都会找这个服务生,那么上面的代码就可以工作。
一个线程中怎么会有两个WAIT呢?
厨师--服务员:厨师提供做好的菜让服务员送餐;
服务员--顾客:顾客点菜后要服务员下单。看来还是要引入命令队列,会让这个模型显得更清晰和简单点:
做个服务员的命令队列,厨师和顾客都向这个队列中放入自己的呼叫,放入后即等待该呼叫被处理。
服务员则从该队列中获取任务,根据是厨师任务还是顾客任务分别进行处理,完成后唤醒厨师或顾客,然后继续从队列找下一个任务。这样做应该会更清晰些。。