shutdown和awaitTermination哪个第一次调用有什么区别?

时间:2013-08-25 02:17:49

标签: java multithreading executorservice

之间有什么区别
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()可以终止已提交但未完成的任务?我尝试了一些例子,他们没有证明,请举个例子。

9 个答案:

答案 0 :(得分:39)

您应该先致电shutdown。否则,您可能需要等待很长时间,因为awaitTermination实际上并未关闭执行程序。

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

答案 1 :(得分:36)

阅读文档总是有帮助:

shutdownNow

  

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

     

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

     

除了努力尝试停止处理之外,没有任何保证   积极执行任务。此实现通过取消任务   Thread.interrupt(),所以任何无法响应中断的任务   可能永远不会终止

<强> shutdown

  

启动有序关闭,其中以前提交的任务   已执行,但不会接受任何新任务。调用没有   如果已经关闭,则会产生额外的影响。

     

此方法不会等待先前提交的任务完成   执行。使用awaitTermination来执行此操作。

<强> awaitTermination

  

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

答案 2 :(得分:13)

shutdown表示执行程序服务不再接收传入任务。

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()) {

}

通过这种方式,您可以确保所有线程都已完成运行,除非它们意外中断。

答案 3 :(得分:2)

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

答案 4 :(得分:2)

主要区别

关机()-

1. Not block the calling a thread - means a thread who called the shutdown().
2. Excecutor not accepting new task after calling shutdown().

awaitTermination -

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

混乱点- 因为shutdown()不会杀死先前提交的任务,所以为什么要使用awaitTermination()

shutdown()也不会杀死任何先前提交的任务,这意味着已提交的任务和当前正在运行的任务被允许继续,那么为什么需要awaitTermination()。

假设您只能等待 10分钟来完成所有提交的任务,然后要调用shutdownNow()(---您已经知道它在做什么),然后使用awaitTermination( ),然后调用shutdown()。

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

答案 5 :(得分:1)

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();
}

答案 6 :(得分: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方法将在超时之前不返回。这就解释了为什么要等很长时间才能先等待然后关闭。

答案 7 :(得分:0)

最佳实现:

executor.shutdown();
    try {
         if (!executor.awaitTermination(3500, TimeUnit.MILLISECONDS)) {
            executor.shutdownNow();
         }                  
    } catch (InterruptedException e) {              
        executor.shutdownNow();
    }

答案 8 :(得分:-2)

在awaitTermination()方法调用发生后,您需要调用shutdownNow()方法。然后,只有你可以找出awaitTermination()方法的实际用法