Timer already cancelled 异常分析  
   
所属分类 java
浏览量 2480
定时任务不建议使用 Timer ,推荐使用 ScheduledExecutorService
 Timer和ScheduledExecutorService的区别 
TimerTask 如果抛出没有 catch的异常 ,Timer 会被 cancel 
后续再执行任务时 会抛出异常
java.lang.IllegalStateException: Timer already cancelled.
某业务 使用 Apache Commons pool 时 碰到了该异常
该异常实例演示
https://gitee.com/dyyx/hellocode/blob/master/src/dyyx/timer/TimerAlreadyCancelledTest.java
Timer
public void cancel() {
        synchronized(queue) {
            thread.newTasksMayBeScheduled = false;
            queue.clear();
            queue.notify();  // In case queue was already empty.
        }
    }
    
    
TimerThread
public void run() {
        try {
            mainLoop();
        } finally {
            // Someone killed this Thread, behave as if Timer cancelled
            synchronized(queue) {
                newTasksMayBeScheduled = false;
                queue.clear();  // Eliminate obsolete references
            }
        }
    }
    
    
TimerTask 运行抛出异常时 ,  mainLoop 会退出 ,运行 finally , 等同于执行了 cancel()
执行定时任务时   newTasksMayBeScheduled 为 false 时 , 抛出异常
java.lang.IllegalStateException: Timer already cancelled.
  private void sched(TimerTask task, long time, long period) {
        if (time < 0)
            throw new IllegalArgumentException("Illegal execution time.");
        // Constrain value of period sufficiently to prevent numeric
        // overflow while still being effectively infinitely large.
        if (Math.abs(period) > (Long.MAX_VALUE >> 1))
            period >>= 1;
        synchronized(queue) {
            if (!thread.newTasksMayBeScheduled)
                throw new IllegalStateException("Timer already cancelled.");
 上一篇  
   
 下一篇  
 微服务架构优雅停机 
 基本的社交礼仪 
 Cookie Session 和 Token 
 drools简介及实例 
 redis单线程为什么还那么快 
 redis的VM机制