我想管理由TaskExecutor返回的Futures对象列表 我有类似的东西
List<Future<String>> list
void process(ProcessThis processThis) {
for ( ...) {
Future<String> future = taskExecutor.submit(processThis);
list.add(future)
}
}
void removeFutures() {
for(Future future : list) {
assert future.cancel(true);
}
ProcessThis是一个实现Callable&lt;的任务。串GT;并检查Thread.interrupted()状态
public String call() {
while (true) {
if (Thread.interrupted()) {
break;
}
doSomething();
}
}
现在的问题是,当调用Thread.interrupted()时,只有并发线程的子集返回'true'。
removeFutures()中的断言为每个被删除的未来返回true(我也检查了isDone()和isCompleted()。
被中断的线程数是随机的。超过15个运行的线程有时13个被中断,有时2 ...
我真的不明白问题出在哪里。如果我调用future.cancel(true)并返回true ...然后我检查Thread.interrupted(这只被调用一次),我希望这也会返回true。
知道我错过了什么吗?
我正在构建java 1.6.0_02-b05
答案 0 :(得分:6)
请注意,Thread.interrupted()
会返回当前中断状态,然后将其清除,因此以后所有调用都将返回false。你想要的可能是Thread.currentThread().isInterrupted()
。
另请注意,如果任务已经完成或取消,future.cancel(true)
通常只会返回false。如果它返回true,则不能保证任务实际上将被取消。
doSomething()
发生了什么?由于中断,RuntimeException可能会在某处转义。你有UncaughtExceptionHandler套吗?如果没有,您需要将ThreadFactory传递给Executor
,{{1}}将设置异常处理程序并记录任何错过的异常。
答案 1 :(得分:2)
至少,您应该恢复中断标志,以使taskExecutor意识到线程中断:
public String call() {
while (true) {
if (Thread.interrupted()) {
Thread.currentThread().interrupt();
break;
}
doSomething();
}
}
答案 2 :(得分:2)
经常吞下中断的潜在问题。因此,在doSomething()
深处(甚至在类加载中)的某个地方,中断可能会被wait()
捕获,然后被'粗心'代码丢弃。中断是邪恶的,IMO。
可能值得检查所有任务是否在取消时实际运行。