面试官:Java中线程池是如何复用线程的?

  • 时间:2025-12-06 22:52 作者: 来源: 阅读:0
  • 扫一扫,手机访问
摘要:线程池的本质是通过预先创建一批线程,当有任务加入时直接使用预先创建的线程处理任务,一方面避免了即时创建线程带来的性能损耗,另一方面也可以更好的管理整个应用的线程使用情况,列如控制最大线程数、任务排队等。一个线程的生命周期为:新建 ---> 运行 ---> 阻塞 ---> 死亡当一个线程执行完后会进入到死亡状态,这个时候线程就不存在了,那么 JDK 中的线程池是如何“复用”一个线程

线程池的本质是通过预先创建一批线程,当有任务加入时直接使用预先创建的线程处理任务,一方面避免了即时创建线程带来的性能损耗,另一方面也可以更好的管理整个应用的线程使用情况,列如控制最大线程数、任务排队等。

一个线程的生命周期为:

新建 ---> 运行 ---> 阻塞 ---> 死亡

当一个线程执行完后会进入到死亡状态,这个时候线程就不存在了,那么 JDK 中的线程池是如何“复用”一个线程的呢?

答案是 ThreadPoolExecutor 中的 keepAliveTime 参数,它的作用是控制 ThreadPoolExecutor 中 Worker 工作线程从工作队列中获取任务的超时时间,当工作队列中没有任务时,将会阻塞,直到满足 keepAliveTime 超时时间后进入到死亡状态。

换句话说 keepAliveTime 参数会将线程状态保存在阻塞状态,从而等待执行后续加入到工作队列的任务以完成线程复用的目的。

try {
  Runnable r = timed ?
  	workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
  	workQueue.take();
  if (r != null)
    return r;
  timedOut = true;
} catch (InterruptedException retry) {
  timedOut = false;
}

代码上使用了 BlockingQueue 阻塞队列来存储工作任务,使用 poll(keepAliveTime) 阻塞方法来获取工作任务。

当然如果在 keepAliveTime 后依旧没有任务,当前线程依旧会进入到死亡状态,后续加入的任务会有线程池中其它线程或者创建新的线程来执行。

  • 全部评论(0)
手机二维码手机访问领取大礼包
返回顶部