关于Timer already cancelled以及Task already scheduled or cancelled问题

1、问题的原因

我们想要设置一个开关,控制定时器的状态。当我们关掉开关的时候,也就是在使用task.cancel()或者timer.cancel()来取消定时任务后再调用原来的定时任务时,可能会出现这两种错误,原因是因为每个task和timer都是一次性的消耗品,当使用cancel方法后,这个task和timer就被消耗掉了,想要再次使用就只能再次创建新的task和timer。如下:

2 、解决办法

方式一:

所有task共用一个timer。每次使用task.cancel()取消定时器,每次启动的时候,再重新new一个TimerTask。

public static void main(String[] args) throws InterruptedException {
        Timer timer = new Timer();
        TimerTask task1 = new TimerTask() {
            int i=0;
            @Override
            public void run() {
                System.out.println(" abc:" + (++i));
            }
        };
        timer.scheduleAtFixedRate(task1, 1000 , 1000);
        Thread.sleep(5000);
        task1.cancel();
//        timer.purge();
//        timer = new Timer();
        task1 = new TimerTask() {
            int i=0;
            public void run() {

                System.out.println(" abc:" + (++i));
            }
        };
        timer.scheduleAtFixedRate(task1, 1000 , 1000);
    }

结果:

Timer already cancelled 或者 Task already scheduled or cancelled_System

方式二:

每次使用Timer.cancel()取消定时器,每次启动的时候,再重新new一个TimerTask也要new一个Timer

public static void main(String[] args) throws InterruptedException {
        Timer timer = new Timer();
        TimerTask task1 = new TimerTask() {
            int i=0;
            @Override
            public void run() {
                System.out.println(" abc:" + (++i));
            }
        };
        timer.scheduleAtFixedRate(task1, 1000 , 1000);
        Thread.sleep(5000);
        timer.cancel();
        timer.purge();
        timer = new Timer();
        task1 = new TimerTask() {
            int i=0;
            @Override
            public void run() {
                System.out.println(" abc:" + (++i));
            }
        };
        timer.scheduleAtFixedRate(task1, 1000 , 1000);
    }

结果:

Timer already cancelled 或者 Task already scheduled or cancelled_System_02

总结:这两种方式,都需要重新new TimerTask,不同的是,cancel的对象不同。如果采用方式二,cancel了Timer,就还需要new Timer()。

Tips:

方式二,不仅要调用Timer.cancel(),还需要调用Timer.purge()。

 

更多内容请关注微信公众号“外里科技

官方公众号

外里科技

运营公众号

英雄赚





开源代码

https://gitee.com/B_T/beimi

Timer already cancelled 或者 Task already scheduled or cancelled_公众号_03