2012-11-25 9 views
6

FIFO 큐에서 입력 (큐 대기열) 및 출력 (대기열에서 제거)을 관리하는 데 두 개의 타이머가 있지만 큐를 대기열에서 제외하는 예외가 계속 발생합니다. 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 : 타이머가 이미 취소되었습니다. java.util.Timer.sched (Timer.java:354) java.util.Timer.schedule에서 \t (Timer.java:222) RunSim.start에서 \t (RunSim.java:83)에서 \t \t에서 RunSim.main (RunSim.java:47) 줄 83 : t2.schedule (새 removePacket(), 5,5); – Vhas

답변

9

모든 타이머를 예약 한 직후 취소합니다. 이 경우 shutdown — 번으로 전화하면 타이머 및 모든 예약 된 작업이 실제로 취소됩니다. ExecutorService처럼 작동하지 않습니다.

코드의 또 다른 문제점은 바로 System.exit으로 전화를 걸어 예약 된 작업을 실제로 실행하지 않아도된다는 것입니다.

이전 작업에서 예외가 발생한 경우 Timer already canceled 예외가 발생할 수 있습니다. 예외는 어디에서도 볼 수 없지만 타이머를 취소합니다. 타이머 작업을 포괄적 인 try-statement로 래핑하십시오.

+0

내가 그 라인을 가지고 있지 않았을 때조차도 t2는 신비하게 취소 할 것입니다. 그러나 나는 그들을 제거 할 것이다. – Vhas

+2

catch-all 블록에서 작업을 래핑하는 것이 중요합니다. 예를 들어, stop 메서드가 호출 되었기 때문에 타이머의 작업 실행 스레드가 예기치 않게 종료되면 타이머에서 작업을 예약하려고 시도하면 IllegalStateException이 발생하고, 마치 타이머의 cancel 메소드가 호출 된 것처럼. " 핵심 비트가 "예기치 않게 종료됩니다"... –