ExecutorService shutdown()和shutdownNow()的区别
2023-10-13 03:06:41
线程池中的关机与重新启动:shutdown() 与 shutdownNow()
在多线程编程中,线程池 是一种强大的工具,可以帮助我们管理并发任务。它通过预先分配一定数量的线程来减少创建和销毁线程的开销。当需要执行任务时,线程池会从其可用线程池中分配一个线程来执行该任务。
ExecutorService 是 Java 中用来管理线程池的类。它提供了一系列方法来管理线程池,包括shutdown() 和 shutdownNow() ,这两个方法用于关闭线程池。但是,它们之间存在一些关键的区别。
shutdown()
shutdown() 方法会等待线程池中的所有任务执行完毕后再关闭线程池。如果线程池中还有任务正在执行,则 shutdown() 方法会返回 false 。如果线程池中没有任务正在执行,或者所有任务都已执行完毕,则 shutdown() 方法会返回 true 。
代码示例:
ExecutorService executorService = Executors.newFixedThreadPool(10);
// 提交任务到线程池
executorService.submit(() -> System.out.println("任务 1"));
executorService.submit(() -> System.out.println("任务 2"));
// 等待所有任务执行完毕再关闭线程池
executorService.shutdown();
// 检查线程池是否已关闭
if (executorService.isShutdown()) {
System.out.println("线程池已关闭");
}
shutdownNow()
shutdownNow() 方法会立即关闭线程池,不管线程池中的任务是否执行完毕。shutdownNow() 方法会返回一个 List ,其中包含了所有因线程池关闭而被中断的任务。
代码示例:
ExecutorService executorService = Executors.newFixedThreadPool(10);
// 提交任务到线程池
executorService.submit(() -> System.out.println("任务 1"));
executorService.submit(() -> System.out.println("任务 2"));
// 立即关闭线程池,并获取被中断的任务列表
List<Runnable> interruptedTasks = executorService.shutdownNow();
// 检查被中断的任务
for (Runnable task : interruptedTasks) {
System.out.println("任务 " + task + " 已被中断");
}
shutdown() 与 shutdownNow() 的区别
shutdown() 和 shutdownNow() 方法之间的主要区别在于:
- shutdown() 会等待线程池中的所有任务执行完毕后再关闭线程池,而 shutdownNow() 会立即关闭线程池,不管线程池中的任务是否执行完毕。
- shutdown() 如果线程池中还有任务正在执行,会返回 false ,如果线程池中没有任务正在执行,或者所有任务都已执行完毕,会返回 true 。shutdownNow() 会返回一个 List ,其中包含了所有因线程池关闭而被中断的任务。
使用建议
在大多数情况下,我们都应该使用 shutdown() 方法来关闭线程池。shutdown() 方法可以保证线程池中的所有任务都能执行完毕,不会丢失任何任务。只有在特殊情况下,比如当线程池中的任务非常耗时,并且我们不想等待任务执行完毕时,我们才应该使用 shutdownNow() 方法来关闭线程池。
总结
shutdown() 和 shutdownNow() 方法是 ExecutorService 类中用来关闭线程池的方法。shutdown() 会等待线程池中的所有任务执行完毕后再关闭线程池,而 shutdownNow() 会立即关闭线程池,不管线程池中的任务是否执行完毕。在大多数情况下,我们都应该使用 shutdown() 方法来关闭线程池。只有在特殊情况下,比如当线程池中的任务非常耗时,并且我们不想等待任务执行完毕时,我们才应该使用 shutdownNow() 方法来关闭线程池。
常见问题解答
-
什么时候应该使用 shutdown() 方法?
- 当我们需要等待线程池中的所有任务执行完毕后再关闭线程池时。
-
什么时候应该使用 shutdownNow() 方法?
- 当线程池中的任务非常耗时,并且我们不想等待任务执行完毕时。
-
shutdown() 方法返回什么?
- 如果线程池中还有任务正在执行,则返回 false 。如果线程池中没有任务正在执行,或者所有任务都已执行完毕,则返回 true 。
-
shutdownNow() 方法返回什么?
- 一个 List ,其中包含了所有因线程池关闭而被中断的任务。
-
关闭线程池后会发生什么?
- 线程池中的所有线程都将被终止,并且无法再提交新的任务。