TimerTask.cancel() 与 Timer.cancel() 的区别

        TimerTask.cancel() 与 Timer.cancel() 都可以理解为清除任务队列中的任务。看源码

        TimerTask.cancel() 

    /**
     * Cancels this timer task.  If the task has been scheduled for one-time
     * execution and has not yet run, or has not yet been scheduled, it will
     * never run.  If the task has been scheduled for repeated execution, it
     * will never run again.  (If the task is running when this call occurs,
     * the task will run to completion, but will never run again.)
     *
     * <p>Note that calling this method from within the <tt>run</tt> method of
     * a repeating timer task absolutely guarantees that the timer task will
     * not run again.
     *
     * <p>This method may be called repeatedly; the second and subsequent
     * calls have no effect.
     *
     * @return true if this task is scheduled for one-time execution and has
     *         not yet run, or this task is scheduled for repeated execution.
     *         Returns false if the task was scheduled for one-time execution
     *         and has already run, or if the task was never scheduled, or if
     *         the task was already cancelled.  (Loosely speaking, this method
     *         returns <tt>true</tt> if it prevents one or more scheduled
     *         executions from taking place.)
     */
    public boolean cancel() {
        synchronized(lock) {
            boolean result = (state == SCHEDULED);
            state = CANCELLED;
            return result;
        }
    }

        Timer.cancel(): 

    /**
     * Terminates this timer, discarding any currently scheduled tasks.
     * Does not interfere with a currently executing task (if it exists).
     * Once a timer has been terminated, its execution thread terminates
     * gracefully, and no more tasks may be scheduled on it.
     *
     * <p>Note that calling this method from within the run method of a
     * timer task that was invoked by this timer absolutely guarantees that
     * the ongoing task execution is the last task execution that will ever
     * be performed by this timer.
     *
     * <p>This method may be called repeatedly; the second and subsequent
     * calls have no effect.
     */
    public void cancel() {
        synchronized(queue) {
            thread.newTasksMayBeScheduled = false;
            queue.clear();
            queue.notify();  // In case queue was already empty.
        }
    }

        从源码中可以看出,TimerTask.cancel() 只是将当前正在执行的任务终止,state = CANCELLED,return true;如果当前任务已经执行结束,也是将当前任务终止,return false。由此我们也可以看出,当同一项任务调用多次 .cancel() 方法时,该方法只会有效执行一次。而Timer.cancel() 是将当前定时任务中的所有正在运行的任务都清除,使timer没有可执行的任务。所以两者的区别之处在TimerTask.cancel() 只是将当前任务终止,也可以理解为从定时任务(任务队列)中清除掉,但实际上并没有对Timer进行任何操作,所以在调用 TimerTask.cancel() 时,Timer定时任务(任务队列)中的其它任务还是正常执行,不会影响其它任务的正常执行而Timer.cancel() 是将整个定时任务(任务队列)的中的所有任务全部清除

       是不是调用了cancel()后任务会立即结束呢?我们从TimerTask.cancel源码的注释中也可以看到,If the task is running when this call occurs, the task will run to completion, but will never run again. 大概意思就是 当调用TimerTask.cancel() 方法时,该任务正在运行中,这项任务会正常运行到结束,但不会再次运行。同样的在Timer.cancel源码的注释中也可以看到一个类似的解释Does not interfere with a currently executing task (if it exists)翻译为中文大概就是 不干扰当前正在运行的任务(如果存在)。说明当调用cancel()方法后,当前正在运行的任务还能正常运行下去,还有一口气能把这项任务执行完毕,当任务执行完毕后,下次不会再执行,而没有开始执行的任务也不会执行

测试

测试1:task1和task2都不执行cancel()

public class TestTimerCancel {

    public static void main(String args[]) throws ParseException, InterruptedException {
        Timer timer = new Timer();
        TimerTask task1 =  new TimerTask() {
            @Override
            public void run() {
                System.out.println("任务执行时间1:" + this.scheduledExecutionTime());
                // this.cancel();
                // timer.cancel();
            }
        };
        TimerTask task2 =  new TimerTask() {
            @Override
            public void run() {
                System.out.println("任务执行时间2:" + this.scheduledExecutionTime());
                // this.cancel();
                // timer.cancel();
            }
        };
        
        long delay1 = 1000;      // 任务延迟毫秒数
        long delay2 = 2000;      // 任务延迟毫秒数
        long period = 1000;      // 任务间隔毫秒数
        timer.schedule(task1, delay1, period);
        timer.schedule(task2, delay2, period);
    }
}

测试结果:两个任务正常执行

任务执行时间1:1547991032207
任务执行时间2:1547991033208
任务执行时间1:1547991033208
任务执行时间1:1547991034209
任务执行时间2:1547991034209
任务执行时间2:1547991035224
任务执行时间1:1547991035224
任务执行时间1:1547991036225
任务执行时间2:1547991036225
任务执行时间2:1547991037226
任务执行时间1:1547991037226
任务执行时间1:1547991038227
任务执行时间2:1547991038227

测试2:仅task1调用TimerTask.cancel()

TimerTask task1 =  new TimerTask() {
    @Override
    public void run() {
        System.out.println("任务执行时间1:" + this.scheduledExecutionTime());
        this.cancel();
    }
};

测试结果:task1只执行了1次,调用TimerTask.cancel()不影响其它任务的正常执行

任务执行时间1:1547991235852
任务执行时间2:1547991236854
任务执行时间2:1547991237857
任务执行时间2:1547991238859
任务执行时间2:1547991239860
任务执行时间2:1547991240875
任务执行时间2:1547991241890
任务执行时间2:1547991242895
任务执行时间2:1547991243900
任务执行时间2:1547991244906

测试3:仅task1调用Timer.cancel()

TimerTask task1 =  new TimerTask() {
    @Override
    public void run() {
        System.out.println("任务执行时间1:" + this.scheduledExecutionTime());
        timer.cancel();
    }
};

测试结果:仅task1执行了一次,task2没有执行。

任务执行时间1:1547991575545

 测试4:仅task2调用TimerTask.cancel()

TimerTask task2 =  new TimerTask() {
    @Override
    public void run() {
        System.out.println("任务执行时间2:" + this.scheduledExecutionTime());
        this.cancel();
    }
};

测试结果:task2仅执行了一次,task1正常进行固定延迟执行

任务执行时间1:1547991944113
任务执行时间2:1547991945126
任务执行时间1:1547991945126
任务执行时间1:1547991946130
任务执行时间1:1547991947144
任务执行时间1:1547991948147
任务执行时间1:1547991949161
任务执行时间1:1547991950162
任务执行时间1:1547991951175

测试5:仅task2调用Timer.cancel()

TimerTask task2 =  new TimerTask() {
    @Override
    public void run() {
        System.out.println("任务执行时间2:" + this.scheduledExecutionTime());
        timer.cancel();
    }
};

测试结果:task1 和task2都仅执行了一次。由于task1早于task2执行,task2在执行时task1处于执行完毕或者执行中,所以task2执行完后,整个任务队列清除。task2仅能执行一次,task1的执行次数跟task2执行结束时间有关,task2执行结束时间越晚task1执行次数越多。

任务执行时间1:1547992056180
任务执行时间2:1547992057187

测试6:task1调用TimerTask.cancel(),task2调用Timer.cancel()

TimerTask task1 =  new TimerTask() {
    @Override
    public void run() {
        System.out.println("任务执行时间1:" + this.scheduledExecutionTime());
        this.cancel();
        // timer.cancel();
    }
};
TimerTask task2 =  new TimerTask() {
    @Override
    public void run() {
        System.out.println("任务执行时间2:" + this.scheduledExecutionTime());
        // this.cancel();
        timer.cancel();
    }
};

测试结果:task1和task2都仅执行一次

任务执行时间1:1547992543756
任务执行时间2:1547992544753

测试7:task1调用Timer.cancel(),task2调用TimerTask.cancel()

TimerTask task1 =  new TimerTask() {
    @Override
    public void run() {
        System.out.println("任务执行时间1:" + this.scheduledExecutionTime());
        // this.cancel();
        timer.cancel();
    }
};
TimerTask task2 =  new TimerTask() {
    @Override
    public void run() {
        System.out.println("任务执行时间2:" + this.scheduledExecutionTime());
        this.cancel();
        // timer.cancel();
    }
};

测试结果:仅task1执行了1次

任务执行时间1:1547992633651

 

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要重置 Timer 的时间,你可以调用 Timer 的 cancel() 方法和 TimerTask 的 cancel() 方法来停止当前的计时器任务,然后创建一个新的 Timer 对象并为其分配一个新的 TimerTask 对象来启动一个新的计时器任务。 以下是一个简单的示例代码,用于创建一个 Timer 对象并启动 TimerTask 对象,然后在一定时间后重置 Timer: ``` import java.util.Timer; import java.util.TimerTask; public class TimerExample { private static Timer timer; private static TimerTask timerTask; private static final int INTERVAL = 1000; // 1 second public static void main(String[] args) { startTimer(); // Wait for 5 seconds try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } resetTimer(); // Wait for 5 seconds try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } stopTimer(); } private static void startTimer() { timer = new Timer(); timerTask = new TimerTask() { @Override public void run() { System.out.println("TimerTask is running"); } }; timer.schedule(timerTask, 0, INTERVAL); } private static void resetTimer() { timerTask.cancel(); timer.cancel(); startTimer(); } private static void stopTimer() { timerTask.cancel(); timer.cancel(); } } ``` 在该示例中,startTimer() 方法用于创建 TimerTimerTask 对象,并使用 schedule() 方法启动计时器任务。resetTimer() 方法用于停止当前的计时器任务,并重新创建一个 TimerTimerTask 对象来启动一个新的计时器任务。stopTimer() 方法用于停止当前的计时器任务。在 main() 方法中,我们首先调用 startTimer() 方法来启动计时器任务,然后等待 5 秒钟。然后,我们调用 resetTimer() 方法来重置计时器任务并等待另外 5 秒钟。最后,我们调用 stopTimer() 方法来停止计时器任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值