22

I have two timers to manage input(en-queue) and output (dequeue) from a FIFO queue but I keep getting a exception for the dequeueing java.lang.IllegalStateException: Timer already cancelled. I can't place a stop to debug line where the error is claimed to occur line 83. I don't know what I'm missing so any help would be appreciated.

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

        }
    }
}
Vhas
  • 233
  • 1
  • 2
  • 5
  • 1
    And the full stack trace of the exception is...? And line 83 is... ? – JB Nizet Nov 25 '12 at 14:51
  • java.lang.IllegalStateException: Timer already cancelled. at java.util.Timer.sched(Timer.java:354) at java.util.Timer.schedule(Timer.java:222) at RunSim.start(RunSim.java:83) at RunSim.main(RunSim.java:47) Line 83: t2.schedule(new removePacket(),5,5); – Vhas Nov 25 '12 at 17:56

1 Answers1

20

Immediately after scheduling all the timers, you cancel them. This doesn't work like the ExecutorService where you can schedule all you need and then call shutdown—this actually cancels the timer and all scheduled tasks.

Another problem with your code is that you call System.exit right away, not giving any chance to the scheduled tasks to actually run.

Apart from those problems, you may get a Timer already canceled exception if a previous task threw an exception. The exception will not be seen anywhere, but it will cancel the timer. Be sure to wrap your timer tasks into a catch-all try-statement.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • 1
    Even when I didn't have those lines timer t2 would mysteriously cancel. But i'll remove them. – Vhas Nov 25 '12 at 14:54
  • 12
    The point about wrapping a task in a catch-all block is crucial. The Timer documentation refers to this (elliptically, IMO) by saying: "If the timer's task execution thread terminates unexpectedly, for example, because its stop method is invoked, any further attempt to schedule a task on the timer will result in an IllegalStateException, as if the timer's cancel method had been invoked." The key bit being "terminates unexpectedly"... – Allen George Oct 06 '13 at 05:48