为什么TimerTask不能重新使用新的Timer对象?

H2O*_*aCl 9 java timer

Timer(java.util.Timer)文档描述了cancel方法为一个影响该定时器和它指出定时器不能消除之后被使用.所以我实例化一个新的Timer.为什么不让我重复使用task0这个例子中的参数?我甚至没有调用purge哪个被描述为使GC符合条件的任务.在可能被解释为其他情况之前,我声称Timer类不应该影响TimerTask仅仅作为参数的对象.

import java.util.Timer;
import java.util.TimerTask;

public class Tester {

    public static void main(String[] args) throws InterruptedException {
        long delay = 3000L;

        Timer timer0 = new Timer();
        Task task0 = new Task();
        timer0.schedule(task0, delay);
        timer0.cancel();

        Timer timer1 = new Timer();
        timer1.schedule(task0, delay); // throws an exception if we use task0

        Thread.sleep(5000);
        timer1.cancel();
    }
}

class Task extends TimerTask {
    Task() {
    }
    @Override
    public void run() {
        System.out.println("task was invoked");
    }
}
Run Code Online (Sandbox Code Playgroud)

aio*_*obe 5

允许这样会容易出错,因为task0当另一个计时器再次安排时,它仍然可以运行.(注意,cancel()不会终止任务.)

请注意,如果task0由单个管理Timer,则相同的任务将永远不会与其自身同时执行(无论是以固定延迟还是以固定速率执行).

如果你真的想这样的行为,各地将工作让task0task1包装一个共同的目标:

class Task extends TimerTask {
    Runnable runnable;
    Task(Runnable runnable) {
        this.runnable = runnable;
    }
    @Override
    public void run() {
        runnable.run();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样执行:

// "Wrapped" (and thus shared) by task0 and task1 below.
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("task was invoked");
    }
}



Timer timer0 = new Timer();
Task task0 = new Task(runnable);
timer0.schedule(task0, delay);
timer0.cancel();


Task task1 = new Task(runnable);
Timer timer1 = new Timer();
timer1.schedule(task1, delay); // throws an exception if we use task0

Thread.sleep(5000);
timer1.cancel();
Run Code Online (Sandbox Code Playgroud)