2012-11-25 47 views
6

我有兩個定時器來管理FIFO隊列的輸入(en-queue)和輸出(出隊),但我不斷收到出隊java.lang.IllegalStateException異常:定時器已經取消。我不能停止調試錯誤聲稱發生線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行是...? –

+0

java.lang.IllegalStateException:計時器已經取消。 \t在java.util.Timer.sched(Timer.java:354) \t在java.util.Timer.schedule(Timer.java:222) \t在RunSim.start(RunSim.java:83) \t在RunSim.main(RunSim.java:47) 83行:t2.schedule(new removePacket(),5,5); – Vhas

回答

9

在調度完所有定時器之後,立即取消它們。這不起作用,如ExecutorService,您可以安排您需要的所有時間,然後致電shutdown —這實際上取消了計時器和所有計劃的任務。

您的代碼的另一個問題是您立即致電System.exit,沒有給予計劃任務實際運行的機會。

除了這些問題,如果以前的任務發生異常,您可能會收到Timer already canceled異常。這個異常不會在任何地方看到,但它會取消定時器。一定要把你的計時器任務包裝到一個全面的try-statement中。

+0

即使當我沒有這些線時,定時器t2會神祕地取消。但我會刪除它們。 – Vhas

+2

關於將任務封裝在全部區塊中的觀點至關重要。定時器文檔通過說:「如果定時器的任務執行線程意外終止,例如,因爲它的停止方法被調用,任何進一步嘗試在定時器上安排任務將導致IllegalStateException,就好像定時器的取消方法已被調用一樣。「關鍵是「意外終止」... –