返回

ExecutorService shutdown()和shutdownNow()的区别

见解分享

线程池中的关机与重新启动: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 ,如果线程池中没有任务正在执行,或者所有任务都已执行完毕,会返回 trueshutdownNow() 会返回一个 List ,其中包含了所有因线程池关闭而被中断的任务。

使用建议

在大多数情况下,我们都应该使用 shutdown() 方法来关闭线程池。shutdown() 方法可以保证线程池中的所有任务都能执行完毕,不会丢失任何任务。只有在特殊情况下,比如当线程池中的任务非常耗时,并且我们不想等待任务执行完毕时,我们才应该使用 shutdownNow() 方法来关闭线程池。

总结

shutdown()shutdownNow() 方法是 ExecutorService 类中用来关闭线程池的方法。shutdown() 会等待线程池中的所有任务执行完毕后再关闭线程池,而 shutdownNow() 会立即关闭线程池,不管线程池中的任务是否执行完毕。在大多数情况下,我们都应该使用 shutdown() 方法来关闭线程池。只有在特殊情况下,比如当线程池中的任务非常耗时,并且我们不想等待任务执行完毕时,我们才应该使用 shutdownNow() 方法来关闭线程池。

常见问题解答

  1. 什么时候应该使用 shutdown() 方法?

    • 当我们需要等待线程池中的所有任务执行完毕后再关闭线程池时。
  2. 什么时候应该使用 shutdownNow() 方法?

    • 当线程池中的任务非常耗时,并且我们不想等待任务执行完毕时。
  3. shutdown() 方法返回什么?

    • 如果线程池中还有任务正在执行,则返回 false 。如果线程池中没有任务正在执行,或者所有任务都已执行完毕,则返回 true
  4. shutdownNow() 方法返回什么?

    • 一个 List ,其中包含了所有因线程池关闭而被中断的任务。
  5. 关闭线程池后会发生什么?

    • 线程池中的所有线程都将被终止,并且无法再提交新的任务。