ExecutorService invokeall 线程池问题

ExecutorService invokeall threadpool issue

我正在努力处理一个用例,其中提交给 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...";
    }

}

Task2Task3 代码也相同,除了这两个 类 在 for 循环检查中使用 Integer.MAX_VALUE。

有两个问题:

1)

根据 Javadoc:

tasks that have not completed are cancelled.

因此您必须编写 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...";
}

How I am finding out my program not terminated clean? I am using netbeans and shows progress bar at bottom right if program doesn't terminate.

如果没有我上面的更新,程序将永远不会结束,因为线程池仍然是 运行。 shutdown 将不执行任何操作,因为任务尚未完成(取消事件)。

2)

根据定义,取消的任务未完成(甚至未开始),因此对 Future 调用 get 将很快失败。你可以问未来是否取消了 Future#isCancelled.