定时器已取消。

22

我有两个定时器来管理FIFO队列的输入(入队)和输出(出队),但是我一直得到一个异常,java.lang.IllegalStateException: Timer already cancelled。我不能在被声称发生错误的第83行放置停止调试线。我不知道我错过了什么,所以希望能得到任何帮助。

import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

/**
 * RunSim
 */
public class RunSim {
    private double arrivalRate = 600;
    private double y;
    private Timer t;
    private Timer t2;
    private Queue fifoQueue;
    private long xy;
    private long fact = 10;
    private int count;
    private int pId;

    public RunSim() {
        Random r = new Random();
        long n = System.currentTimeMillis();
        r.setSeed(n);
        double i = r.nextDouble();
        y = ((1 / arrivalRate) * (Math.log(i)));
        xy = (long) y;
        t = new Timer();
        t2 = new Timer();
        fifoQueue = new Queue();
        count = 0;
        pId = 0;

    }

    public static void main() {
        RunSim rs = new RunSim();
        rs.start();
    }

    public void start() {
        class sendPacket extends TimerTask {
            public void run() {
                Packet p = new Packet();
                p.setId(pId);
                fifoQueue.insert(p);
                p.setArrivalTime();
                System.out.println("ID: " + p.getId() + " Arrival Time: "
                        + p.getArrivalTime() / fact);
                pId++;

            }
        }

        class removePacket extends TimerTask {
            public void run() {
                fifoQueue.first().setDepartureTime();
                System.out.println("ID: " + fifoQueue.first().getId()
                        + " Departure Time: "
                        + fifoQueue.first().getDepartureTime() / fact);
                fifoQueue.remove();
            }
        }

        while (count < 1000) {
            long v = fact * (1 + Math.abs(xy));
            t.schedule(new sendPacket(), 0, v);
            count++;
            t2.schedule(new removePacket(), 5, 5);

        }
    }
}

1
完整的异常堆栈跟踪是什么?第83行是什么? - JB Nizet
java.lang.IllegalStateException: 定时器已被取消。 在 java.util.Timer.sched(Timer.java:354) 在 java.util.Timer.schedule(Timer.java:222) 在 RunSim.start(RunSim.java:83) 在 RunSim.main(RunSim.java:47)第 83 行:t2.schedule(new removePacket(),5,5); - Vhas
1个回答

21

在安排所有计时器之后,您立即取消它们。这与ExecutorService不同,您可以安排需要的所有内容,然后调用shutdown,但这实际上会取消计时器和所有已安排的任务。

代码的另一个问题是您立即调用System.exit,没有给已安排的任务任何运行的机会。

除了这些问题外,如果以前的任务抛出异常,则可能会收到Timer already canceled异常。异常将不会在任何地方显示,但它将取消计时器。请务必将计时器任务包装在捕获所有异常的try语句中。


1
即使我没有那些代码行,计时器t2仍然会神秘地取消。但是我会把它们删除。 - Vhas
12
用一个catch-all块来包装任务非常重要。定时器文档通过以下方式(在我看来是含糊不清的)提到了这一点:“如果定时器的任务执行线程意外终止,例如因为调用了它的stop方法,则任何进一步尝试在定时器上安排任务都会导致IllegalStateException异常,就好像已经调用了定时器的cancel方法一样。” 关键在于“意外终止”这一点... - Allen George

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接