Java 线程池管理生命周期的四个核心方法:shutdown()、shutdownNow()、awaitTermination()、interrupt()

92 阅读2分钟

image.png

🌟 1. shutdown()

  • 作用平滑关闭线程池

  • 机制:

    • 拒绝接收新任务。
    • 已经提交的任务会继续执行(包括队列中的任务)。
  • 不会主动打断正在运行的线程。

  • 状态变化:RUNNING → SHUTDOWN

  • 使用场景:优雅关闭,例如服务停止时等待所有任务完成。


🌟 2. shutdownNow()

  • 作用尽快关闭线程池

  • 机制:

    • 拒绝新任务。
    • 尝试 interrupt() 所有正在运行的线程。
    • 把队列里还没执行的任务取出来返回给调用者。
  • 状态变化:RUNNING → STOP

  • 使用场景:强制停止,例如任务里可能有死循环或需要快速退出时。


🌟 3. awaitTermination(timeout, unit)

  • 作用:阻塞调用线程,等待线程池在指定时间内完全终止。

  • 机制:

    • 必须在调用 shutdown()shutdownNow() 之后使用。

    • 在指定时间内:

      • 如果线程池所有任务完成,返回 true
      • 如果超时还没结束,返回 false
  • 使用场景:常用于优雅关闭时,等待一段时间,如果还没停下来,就强制 shutdownNow()


🌟 4. interrupt()

  • 作用:对单个线程发出中断信号。

  • 机制:

    • 只是设置中断标志位。
    • 线程是否停止,取决于任务代码是否检查 isInterrupted() 或调用阻塞方法时抛 InterruptedException
  • 与线程池的关系:

    • shutdownNow() 内部就是通过调用工作线程的 interrupt() 来请求终止。
  • 使用场景:对单个线程或任务进行优雅取消。


🌟 对比总结

方法是否接收新任务运行中任务队列中任务是否中断线程常见用途
shutdown()❌ 不接收✅ 执行完✅ 执行完❌ 不中断优雅关闭
shutdownNow()❌ 不接收❓ 尝试中断❌ 返回给调用者✅ interrupt尽快关闭
awaitTermination(timeout)-等待直到完成或超时--阻塞调用线程,等待线程池关闭
interrupt() (单个线程)-❓ 看任务是否响应-✅ 设置标志取消某个任务

🌟 最佳实践示例

ExecutorService executor = Executors.newFixedThreadPool(2);

for (int i = 0; i < 5; i++) {
    executor.submit(() -> {
        try {
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println(Thread.currentThread().getName() + " running");
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName() + " interrupted");
            Thread.currentThread().interrupt(); // 恢复中断状态,保证上层能感知
        }
    });
}

// 优雅关闭
executor.shutdown();
try {
    if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
        // 如果5秒还没停,就强制停止
        executor.shutdownNow();
    }
} catch (InterruptedException e) {
    executor.shutdownNow();
}

✅ 总结:

  • shutdown():只是不再接收新任务,等待现有任务完成。
  • shutdownNow():不再接收任务,尝试打断运行中任务,并返回未执行的任务。
  • awaitTermination():阻塞调用线程,等待线程池关闭。
  • interrupt():对单个线程发出中断信号,不会直接杀死线程。

如果觉得有用就点赞收藏加关注吧!