java.util.TimerTask cancel()方法的精确语义

java.util.TimerTask cancel()方法的精确语义,java,timer,Java,Timer,将JavaDoc与真实行为和源代码进行比较时,我对TimerTask cancel方法语义有点不知所措 JavaDoc谈到返回值: 如果任务计划一次性执行且已运行,或者任务从未计划,或者任务已取消,则返回false 但是,如果任务尚未运行,但仍将运行,那么在查看看起来为false的代码时可能会返回。我正在研究java.util.Timer代码mainLoop方法: 因此,从我的角度来看,上面给出的JavaDoc的松散定义看起来确实很严格: 粗略地说,如果此方法阻止一个或多个计划执行的发生,则返回

将JavaDoc与真实行为和源代码进行比较时,我对TimerTask cancel方法语义有点不知所措

JavaDoc谈到返回值:

如果任务计划一次性执行且已运行,或者任务从未计划,或者任务已取消,则返回false

但是,如果任务尚未运行,但仍将运行,那么在查看看起来为false的代码时可能会返回。我正在研究java.util.Timer代码mainLoop方法:

因此,从我的角度来看,上面给出的JavaDoc的松散定义看起来确实很严格:

粗略地说,如果此方法阻止一个或多个计划执行的发生,则返回true

所以,同样,它看起来是假的,因为cancel方法结果可能意味着任务没有执行,但将被执行

请确认我的想法或告诉我哪里错了


谢谢大家!

基本上我同意你的观点,尽管这是一个非常极端的情况

所以,同样,它看起来是假的,因为cancel方法结果可能意味着任务没有执行,但将被执行

更准确的是,任务不会执行,但会立即执行。但由于线程的并发性,简化任务至少正在执行是有用的。因此,javadoc的第二个定义在我看来更加精确:


如果cancel返回true,则表示取消成功,因为至少有一次执行被阻止,无论是一次性任务还是重复任务,在所有其他情况下都是false。

您的理解是正确的,false结果显然不表示任务执行已完成,而表示任务已开始执行

理解task has ready run这个短语最迂腐的方式是,调用cancel无法阻止任务运行。而且,当你考虑它时,这就是cancel的调用者感兴趣的信息

所以,是的,我也同意,松散的条款比严格的条款更严格

请记住,这个Javadoc是在Java平台开发的早期编写的,其质量标准随着时间的推移而不断提高

TimerTask task;
boolean taskFired;
synchronized(queue) {
    // Wait for queue to become non-empty
    while (queue.isEmpty() && newTasksMayBeScheduled)
        queue.wait();
    if (queue.isEmpty())
        break; // Queue is empty and will forever remain; die

    // Queue nonempty; look at first evt and do the right thing
    long currentTime, executionTime;
    task = queue.getMin();
    synchronized(task.lock) {
        if (task.state == TimerTask.CANCELLED) {
            queue.removeMin();
            continue;  // No action required, poll queue again
        }
        currentTime = System.currentTimeMillis();
        executionTime = task.nextExecutionTime;
        if (taskFired = (executionTime<=currentTime)) {
            if (task.period == 0) { // Non-repeating, remove
                queue.removeMin();
                task.state = TimerTask.EXECUTED;
            } else { // Repeating task, reschedule
                queue.rescheduleMin(
                  task.period<0 ? currentTime   - task.period
                                : executionTime + task.period);
            }
        }
    }
    if (!taskFired) // Task hasn't yet fired; wait
        queue.wait(executionTime - currentTime);
}
if (taskFired)  // Task fired; run it, holding no locks
    task.run();
public boolean cancel() {
    synchronized(lock) {
        boolean result = (state == SCHEDULED);
        state = CANCELLED;
        return result;
    }
}