线程池

概念

线程池是指管理一组同构工作线程的资源池。线程池是与工作队列(Work Queue)密切相关的,其中在工作队列中保存了所有等待执行的任务。

工作者线程(Worker Thread)的任务很简单:从工作队列中获取一个任务,执行任务,然后返回线程池并等待下一个任务。

优势

“在线程池中执行任务”比“为每个任务分配一个线程”优势更多:

只有当任务都是同类型的并且相互独立时,线程池的性能才能达到最佳。

  • 如果将运行时间较长的与运行时间较短的任务混合在一起,那么除非线程池很大,否则将可能造成“拥塞”。

  • 如果提交的任务依赖于其他任务,那么除非线程池无限大,否则将可能造成死锁。

线程饥饿死锁

在线程池中,如果任务依赖于其他任务,那么可能产生死锁:

  • 在单线程的 Executor 中,如果一个任务将另一个任务提交到同一个 Executor,并且等待这个被提交任务的结果,那么通常会引发死锁。第二个任务停留在工作队列中,并等待第一个任务完成,而第一个任务又无法完成,因为它在等待第二个任务的完成

  • 在更大的线程池中,如果所有正在执行任务的线程都由于等待其他仍处于工作队列中的任务而阻塞,那么会发生同样的问题。

这种现象被称为线程饥饿死锁(Thread Starvation Deadlock)只要线程池中的任务需要无限期地等待一些必须由池中其他任务才能提供的资源或条件,例如某个任务等待另一个任务的返回值或执行结果,那么除非线程池足够大,否则将发生线程饥饿死锁。

每当提交了一个有依赖性的 Executor 任务时,要清楚地知道可能会出现线程“饥饿”死锁,因此需要在代码或配置 Executor 的配置文件中记录线程池的大小限制或配置限制。

最后更新于