64

和有什么区别

ExecutorService eService = Executors.newFixedThreadPool(2);
eService.execute(new TestThread6());
eService.execute(new TestThread6());
eService.execute(new TestThread6());
eService.awaitTermination(1, TimeUnit.NANOSECONDS);
eService.shutdown();

eService.shutdown();
eService.awaitTermination(1, TimeUnit.NANOSECONDS);

我真的不明白shutdown()。此方法不等待先前提交的任务完成执行。是否意味着shutdown()可以终止已提交但未完成的任务?我尝试了一些例子,他们没有证明这一点,请给我一个例子。

4

9 回答 9

73

你应该shutdown先打电话。否则,您可能会等待很长时间,因为awaitTermination实际上并没有关闭您的执行程序。

如果您想等待任务完成,而不是等待执行程序关闭,那么您应该使用invokeAll.

于 2013-08-25T02:20:07.917 回答
53

阅读文档总是有帮助的:

现在关机

尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。这些任务在从该方法返回时从任务队列中排出(删除)。

此方法不等待主动执行的任务终止。 使用 awaitTermination 来做到这一点。

除了尽最大努力停止处理正在执行的任务之外,没有任何保证。此实现通过 Thread.interrupt() 取消任务,因此任何未能响应中断的任务可能永远不会终止

关机

启动有序关闭,其中执行先前提交的任务,但不会接受新任务。如果已经关闭,调用没有额外的效果。

此方法不等待先前提交的任务完成执行。用来awaitTermination做那个。

等待终止

在关闭请求后阻塞,直到所有任务都完成执行,或者发生超时,或者当前线程被中断,以先发生者为准。

于 2013-08-25T05:29:44.307 回答
20

关闭意味着执行器服务不再接受传入任务。

awaitTermination 在关闭请求后调用。

您需要先关闭服务,然后阻塞并等待线程完成。

如果你想看到所有的线程都运行完并且坚持使用awaiTermination,你需要把 timeout 参数设置的足够大。所以你可以这样做:

eService.shutdown();
if (!eService.awaitTermination(60000, TimeUnit.SECONDS))
    System.err.println("Threads didn't finish in 60000 seconds!");
}

或者,您可以这样做:

eService.shutdown();
while (!eService.isTerminated()) {

}

这样,您就可以确保所有线程都完成运行,除非它们被意外中断。

于 2013-08-25T04:45:55.093 回答
10

主要区别

关机() -

1. Doesn't block the calling a thread i.e. the thread who called the shutdown().
2. Excecutor doesn't accept any new task after calling shutdown().

等待终止() -

1. Blocks the calling thread. (as join() method do)

混淆点:- 如果shutdown() 没有杀死之前提交的任务,为什么我们需要awaitTermination()?

awaitTermination 意味着等待任务完成/终止,对吗?shutdown()正在做同样的事情 - 等待已经与正在运行的任务一起提交的任何任务继续直到完成/终止,那么为什么要使用另一种方法awaitTermination(..)?下面是解释:

假设您只能等待10 分钟以完成所有提交的任务,然后再调用shutdownNow()(---您已经知道它的作用),然后awaitTermination(long timeout, TimeUnit unit)在调用 shutdown() 后使用。

注意 中的方法参数awaitTermination(long timeout, TimeUnit unit)。这个超时是这里的关键。

如果没有时间限制,shutdown() 就可以了。不需要 awaitTermination()。

于 2019-08-06T20:21:10.210 回答
8

最佳实施:

executor.shutdown();
try {
    if (!executor.awaitTermination(3500, TimeUnit.MILLISECONDS)) {
        executor.shutdownNow();
    }                   
} catch (InterruptedException e) {              
    executor.shutdownNow();
}
        
于 2019-10-23T16:52:10.983 回答
3

在我们启动第一个任务之后,ThreadPoolExecutor 将启动一个即使任务完成也不会结束的线程。至少对于固定线程池来说是这样。这就是为什么我们需要调用shutdown。关闭后,ThreadPoolExecutor 将拒绝任何新任务,但会等待正在运行的任务完成,然后允许线程结束。这就是为什么我们在shutdwon 之后需要awaitTermination。

于 2013-08-25T04:33:07.447 回答
2
executorService.execute(runnableTask);  

//executorService.shutdown(); //it will make the executorService stop accepting new tasks
//executorService.shutdownNow(); //tires to destroy the executorService immediately, but it doesn't guarantee that all the running threads will be destroyed at the same time. This method returns list of tasks which are waiting to be processed.
//List<Runnable> notExecutedTasks = executorService.shutdownNow(); //this method returns list of tasks which are waiting to be processed.developer decide what to do with theses tasks?

//one good way to shutdown the executorService is use both of these methods combined with the awaitTermination
executorService.shutdown();
try{
    if(!executorService.awaitTermination(1000, TimeUnit.MICROSECONDS)) {
        executorService.shutdownNow();
    }
}catch (InterruptedException e){
    e.printStackTrace();
}
于 2019-06-17T03:00:40.847 回答
0

从 Java8 ThreadPool awaitTermination 方法:

    try {
        for (;;) {
            if (runStateAtLeast(ctl.get(), TERMINATED))
                return true;
            if (nanos <= 0)
                return false;
            nanos = termination.awaitNanos(nanos);
        }
    } finally {
        mainLock.unlock();
    }

它将首先检查线程池的运行状态。如果线程池没有关闭(将运行状态设置为终止),awaitTermination 方法将不会返回,直到超时。这解释了如果先等待然后关闭,为什么要等待很长时间。

于 2019-08-09T08:15:58.510 回答
-2

您需要在方法调用发生shutdownNow()后调用方法。awaitTermination()然后只有你才能找到方法的实际用法awaitTermination()

于 2018-01-18T10:09:52.183 回答