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

Preserve call stack of, Timer.schedule in java

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

守护进程

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");
        }
    }