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

我用TimerTask的cancel()方法语义丢失了一点,它比较了JavaDoc与真实行为和源代码。

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()可以很容易地在最后面调用,因为TimerTask的cancel()代码只是设置任务状态显然不与任务的run()同步:

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

所以,从我的角度来看,JavaDoc在上述之后给出的“松散”定义确实很严格:

松散地说,如果这个方法阻止一个或多个预定执行发生,则此方法返回true。

所以,再次,它看起来像get()方法结果可能意味着任务没有执行,但将被执行。

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

谢谢!


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

理解“任务已经运行”一词的最迂腐的方式是“事情已经到了cancel呼叫未能阻止任务运行的地步”。 而且,当您考虑它时,这是cancel()的调用者感兴趣的信息。

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

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


基本上我同意你的看法,虽然这是相当极端的情况。

所以,再次,它看起来像get()方法结果可能意味着任务没有执行,但将被执行。

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

如果cancel()返回true,则意味着取消成功的原因是至少有一次进一步的执行被阻止(对于一次或重复任务)并且在所有其他情况下都是false。

链接地址: http://www.djcxy.com/p/74905.html

上一篇: java.util.TimerTask cancel() method exact semantics

下一篇: Cancel a scheduled fixed rate task depending on the result of the task