我目前正在使用 FutureTasks 和 Executors 在多线程环境中寻找一个讨厌的错误。基本思想是让固定数量的线程执行单独的 FutureTasks,计算结果将显示在一张表中(不要介意这里的 GUI 方面)。
看了这么久,开始怀疑自己的智商了。
考虑这段代码:
public class MyTask extends FutureTask<Result> {
private String cellId;
...
protected void done() {
if (isCancelled()) return;
try {
Result r = get(); // should not wait, because we are done
... // some processing with r
sendMessage(cellId, r);
} catch (ExecutionException e) { // thrown from get
...
} catch (InterruptedException e) { // thrown from get
...
}
}
...
}
当done()
由处理 MyTask 实例的 Executor 调用时,我检查我是否到达那里,因为任务已被取消。如果是这样,我会跳过所有剩余的活动,尤其是我不调用sendMessage()
.
FutureTask.done() 的文档说:
当此任务转换到状态 isDone 时调用受保护的方法(无论是正常还是通过取消)。默认实现什么也不做。子类可以覆盖此方法以调用完成回调或执行簿记。请注意,您可以在此方法的执行中查询状态以确定此任务是否已被取消。(API 参考)
但是我没有从文档中得到的是执行时FutureTask
的语义。如果我一开始就通过了检查,但之后其他线程调用了我的方法怎么办?这会导致我的任务改变主意并从那时起回复吗? done()
isCancelled()
cancel()
isCancelled() == true
如果是这样,我以后怎么知道消息是否已发送?看着isDone()
只会告诉我任务的执行已经完成,但当时isCancelled()
也是如此,我不知道它是否能及时发送消息。
也许这很明显,但我现在还没有真正看到。