Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ExecutorService.invokeAll并关闭_Java_Concurrency_Executor - Fatal编程技术网

Java ExecutorService.invokeAll并关闭

Java ExecutorService.invokeAll并关闭,java,concurrency,executor,Java,Concurrency,Executor,因此,我有一些可调用的任务,对中断敏感,我使用invokeAll将其提交给ExecutorService。从另一个方法调用executorService.shutdownNow 5秒钟后,我调用WaitTermination,它返回true,因此一切看起来都很好。问题是执行人永远不会终止 由于日志记录,我知道我的每项任务都已完成。 然而,当i等于执行器的线程数时,invokeAll仍会阻塞f.get: 以下代码来自AbstractExecutorService+一些日志记录 @O

因此,我有一些可调用的任务,对中断敏感,我使用invokeAll将其提交给ExecutorService。从另一个方法调用executorService.shutdownNow 5秒钟后,我调用WaitTermination,它返回true,因此一切看起来都很好。问题是执行人永远不会终止

由于日志记录,我知道我的每项任务都已完成。 然而,当i等于执行器的线程数时,invokeAll仍会阻塞f.get:

以下代码来自AbstractExecutorService+一些日志记录

        @Override
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {
        if (tasks == null) throw new NullPointerException();
        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
        boolean done = false;
        try {
            List<Callable<T>> list = new ArrayList<Callable<T>>();
            for (Callable<T> t : tasks) {
                list.add(t);
                RunnableFuture<T> f = newTaskFor(t);
                futures.add(f);
                execute(f);
            }
            for (int i = 0, size = futures.size(); i < size; i++) {
                Future<T> f = futures.get(i);
                if (!f.isDone()) {
                    log.info("Future %s is not done!. Task %s", i, list.get(i));
                    try {
                        log.info("Get from future %s", i);
                        // NEXT LINE BLOCKS FOR i= NUMBER OF THREADS
                        f.get();
                        log.info("Got result from future %s", i);
                    } catch (CancellationException ignore) {
                    } catch (ExecutionException ignore) {
                    }
                }
            }
            log.info("Obtained all!");
            done = true;
            return futures;
        } finally {
            if (!done) for (int i = 0, size = futures.size(); i < size; i++)
                futures.get(i).cancel(true);
        }
    }
@覆盖

public List invokeAll(Collection是的,您不应该在关机时使用invokeAll。至少这是我的理解,如果我错了,请纠正我

  • Shutdownow方法:
公共列表关闭现在(){
...
checkShutdownAccess();
提前停止(停止);
打断工人();
tasks=drainQueue();
...
}
唯一要做的就是中断工作线程并从工作队列中删除其余的可运行程序,请参见drainQueue。ShutdownNow/Shutdown不会修改我们invokeAll方法中的未来

因此,在我的例子中,对于一个有N个线程的执行器,我调用了300个作业,每个作业都需要1分钟以上的时间,5秒钟后我取消(中断工作线程),N个线程被中断(0到N-1)。剩下的将来会发生什么?,下一次调用f.get()(参见问题中的对应行)将阻塞,而您将被困在那里。这解释了为什么我总是在I=线程数时被阻塞

public List<Runnable> shutdownNow() {
...
        checkShutdownAccess();
        advanceRunState(STOP);
        interruptWorkers();
        tasks = drainQueue();
...
}