【问题标题】:java.util.TimerTask cancel() method exact semanticsjava.util.TimerTask cancel() 方法精确语义
【发布时间】:2014-09-25 12:20:12
【问题描述】:

比较 JavaDoc 与真实行为和源代码的 TimerTask cancel() 方法语义让我有些不知所措。

JavaDoc 关于返回值的说法:

如果任务被安排为一次性执行并且已经运行,或者如果任务从未被安排,或者如果任务已经被取消,则返回 false。

但是,如果任务尚未运行,但查看代码,可能会返回 false,但 运行。我在看 java.util.Timer 代码(mainLoop() 方法):

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();

似乎 cancel() 可以在最后一个 if 之前轻松调用,因为 TimerTask cancel() 代码显然只是设置了任务状态不与任务的 run() 同步:

public boolean cancel() {
    synchronized(lock) {
        boolean result = (state == SCHEDULED);
        state = CANCELLED;
        return result;
    }
}

所以,从我的角度来看,在上面给出的 JavaDoc 中的“松散”定义似乎确实很严格:

简单地说,如果这个方法阻止了一个或多个计划执行的发生,则返回 true。

所以,再一次,看起来像 false 作为 cancel() 方法的结果可能意味着任务没有被执行,但会被执行。

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

谢谢!

【问题讨论】:

    标签: java timer


    【解决方案1】:

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

    理解“任务已经运行”这个短语的最迂腐的方式是“事情已经到了对cancel 的调用无法阻止任务运行的地步”。而且,仔细想想,这就是cancel()的调用者感兴趣的信息。

    所以是的,我也同意“宽松”条款比“严格”条款更严格。

    请记住,此 Javadoc 是在 Java 平台开发的早期编写的,并且随着时间的推移,其质量标准一直在提高。

    【讨论】:

      【解决方案2】:

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

      所以,再一次,cancel() 方法的结果似乎是 false,这可能意味着任务没有被执行,但会被执行。

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

      如果 cancel() 返回 true,则意味着取消成功,至少阻止了进一步执行(对于一次性或重复任务),在所有其他情况下为 false .

      【讨论】:

        猜你喜欢
        • 2015-07-30
        • 1970-01-01
        • 2015-07-06
        • 2014-12-08
        • 1970-01-01
        • 2022-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多