我正在努力处理一个用例,其中提交给invokeall()
的任务之一抛出CancellationException
强制程序不要终止。如果CancellationException
?
我如何发现我的程序未被终止干净?如果程序没有终止,我正在使用netbeans并在右下角显示进度条。
这是代码:
int poolSize = Runtime.getRuntime().availableProcessors();
ExecutorService pool = Executors.newFixedThreadPool(poolSize);
Set<Callable<Object>> tasksSet = new HashSet<>();
tasksSet.add(new Task1());
tasksSet.add(new Task2());
tasksSet.add(new Task3());
List<Future<TrendLineStatisticsVO>> resultSet = pool.invokeAll(tasksSet, 1, TimeUnit.MINUTES);
for (Future<Object> future : resultSet) {
Object result;
try {
result = future.get(5, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
ex.printStackTrace();
Logger.getLogger(CallableDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
ex.printStackTrace();
Logger.getLogger(CallableDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (TimeoutException ex) {
ex.printStackTrace();
Logger.getLogger(CallableDemo.class.getName()).log(Level.SEVERE, null, ex);
}
}
pool.shutdown();
Task1
代码:
public class Task1 implements Callable<Object> {
@Override
public Object call() throws Exception {
//This for sure takes days to complete, so should through Cancellation exception because timeout on invokeall set to 1 minute
long val = 0;
for (long i = 0; i < Long.MAX_VALUE - 5000; i++) {
val += i;
}
return "Sucessfull Task1 object...";
}
}
Task2
和Task3
代码也相同,除了这两个类使用Integer.MAX_VALUE进行循环检查。
答案 0 :(得分:1)
有两个问题:
1)
根据Javadoc:
尚未完成的任务将被取消。
因此,您必须对Task
进行编码,以便对中断做出响应。如果任务在指定的时间内没有完成,则后台发生的情况类似于future.cancel(true)
,参数中的true表示运行任务的线程interrupt()
。就像我提到的,你的任务必须注意中断。类似于:
@Override
public Object call() throws Exception {
//This for sure takes days to complete, so should through Cancellation exception because timeout on invokeall set to 1 minute
long val = 0;
for (long i = 0; i < Long.MAX_VALUE - 5000; i++) {
if(Thread.interruped()){
throw new RuntimeException("Did not complete in time: " + i);
}
val += i;
}
return "Sucessfull Task1 object...";
}
我如何发现我的程序未被终止干净?如果程序没有终止,我正在使用netbeans并在右下方显示进度条。
如果没有上面的更新,程序将永远不会因为线程池仍在运行而结束。由于任务尚未完成(取消事件),shutdown
将无法执行任何操作。
2)
根据定义,取消的任务未完成(甚至启动),因此在Future上调用get
将很快失败。如果它被取消Future#isCancelled
,您可以询问未来。