gpt4 book ai didi

java - 在java中保留Timer.schedule的调用堆栈

转载 作者:行者123 更新时间:2023-12-02 08:45:27 25 4
gpt4 key购买 nike

我有一个正在运行的守护线程,每当厨师不忙并且有订单需要交付时,它就会调用一个函数(prepareOrder)。根据完成订单所需的时间,prepareOrder 在一定时间间隔后调用 orderComplete 函数。现在我面临的问题是只有对prepareOrder的最后一次调用才会显示在sout上。

守护进程

package ui;
import Model.takeOrderModel;
public class daemonThread extends Thread{
//call this method in the main method of driving fucntion
private takeOrderModel orderModel;
daemonThread(takeOrderModel orderModel){
this.orderModel = orderModel;
}
public void assignCook(){
while(true){
int toComplete = orderModel.toCompleteOrders.size();
if ( !orderModel.cookBusy && toComplete>0 ) orderModel.prepareOrder();
}
}
}

准备订单功能。

 public void prepareOrder(){
// pick the last element from list
if (toCompleteOrders.size() > 0){
String nextPrepare = toCompleteOrders.get(toCompleteOrders.size()-1);
order orderToComplete = allOrdersPlaced.get(nextPrepare);
completeOrder(orderToComplete);
toCompleteOrders.remove(nextPrepare);
}
}

//Helper function to prepareOrder moves an order from toComplete to prepared order
private void completeOrder(order orderToComplete){
changeCookState();
new java.util.Timer().schedule(
new java.util.TimerTask(){
@Override
public void run() {
changeCookState();
preparedOrders.add(orderToComplete.id);
deliverOrder(orderToComplete.id);
}
}, (long) (orderToComplete.timeToComplete*60)
);
}

public void changeCookState(){
this.cookBusy = !cookBusy;
}

// MODIFIES removes a order from the prepared list and puts it in delivered list
public String deliverOrder(String completedOrder){
preparedOrders.remove(completedOrder);
deliveredOrders.add(completedOrder);
System.out.println(String.format("The order of %s is here", allOrdersPlaced.get(completedOrder).customerName));
return String.format("The order of %s is here", allOrdersPlaced.get(completedOrder).customerName);
}

主要功能驱动代码。

orderMachine.takeNewOrder(fullMeal, "Tom");
orderMachine.takeNewOrder(halfMeal, "Bob");
daemonThread backThread = new daemonThread(orderMachine);
backThread.setDaemon(true);
backThread.assignCook();

现在对我来说只有最后下的订单(“Bob”)才会打印在 sout 上。 Timer.schedule 创建的所有调用如何保留在堆栈中。

<小时/>

编辑

接受新订单功能。

public boolean takeNewOrder(List<item> itemsInOrder, String customerName){
try {
order newOrder = new order(itemsInOrder, customerName);
allOrdersPlaced.put(newOrder.id, newOrder);
toCompleteOrders.add(newOrder.id);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
<小时/>

编辑2

这里是包含完整代码的公共(public)存储库 https://github.com/oreanroy/Share_code_samples/tree/master/takeOrder

最佳答案

此代码中的问题是并发错误 - 正在从两个不同的线程写入 cookBusy 变量。要解决此问题,请使用 AtomicBoolean 而不是 boolean,因为这是线程安全的。

AtomicBoolean cookBusy = new AtomicBoolean(false);

使用 compareAndSet 确保共享变量在更新之前设置为已知值。

    public void changeCookState(boolean busy){
if (!this.cookBusy.compareAndSet(!busy, busy))
{
throw new RuntimeException("shared variable set to unexpected value");
}
}

关于java - 在java中保留Timer.schedule的调用堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61114266/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com