首页  

Timer already cancelled 异常分析     所属分类 java 浏览量 1763
定时任务不建议使用 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机制