ExecutorService调用threadpool问题

时间:2015-01-15 17:22:48

标签: java multithreading executorservice

我正在努力处理一个用例,其中提交给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代码也相同,除了这两个类使用Integer.MAX_VALUE进行循环检查。

1 个答案:

答案 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,您可以询问未来。