目录

ThreadPool

Executor框架的执行策略可以将任务的提交与执行解耦开来,为任务的制定、执行提供了相当大的灵活性。但并非所有的任务都适用于Executor框架执行策略,有些任务需要明确的指定执行策略。

  • 依赖性任务。依赖性任务注重任务之间的执行顺序。如果线程池执行依赖性任务,需要隐含为执行策略带来约束,避免产生活跃性问题。

  • 使用线程封闭机制的任务。任务要求 Executor 是单线程的,如果将 Executor 从单线程环境改为线程池环境,将会失去线程安全性。

  • 对响应时间敏感的任务。这类任务需要及时响应。如果将一个运行时间较长的任务提交到单线程的 Executor 中,或者将多个运行时间较长的任务提交到一个只包含少量线程的线程池中,那么将降低该 Executor 管理的服务的响应性。

  • 使用ThreadLocal任务。ThreadLocal 使每个线程都拥有某个变量的一个私有“版本”。只要条件允许,Executor 可以自由地重用这些线程。只有当线程本地值的生命周期受限于任务生命周期时,在线程池的线程中使用 ThreadLocal 才有意义,而在线程池的线程中不应该使用 ThreadLocal 在任务之间传递值。

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

依赖性任务可能造成线程池死锁。线程池中如果所有正在执行任务的线程都因等待其他仍处于工作队列中的任务而阻塞,就会引发线程饥饿死锁Thread Starvation Deadlock

如果任务阻塞的时间过长,线程池的响应性也会变得糟糕。此外,运行时间较长的任务也会增加短任务的服务时间。

有一项技术可以缓解执行时间较长任务造成的影响,即限定任务等待资源的时间。在平台类库的大多数可阻塞方法中,都同时定义了限时版本和无限时版本,例如 Thread.joinBlockingQueue.putCountDownLatch.await 以及 Selector.select 等。如果等待超时,那么可以把任务标识为失败,然后中止任务或重新返回队列以便随后执行。

Qian Sun -- Coder💻 | Blogger📝 | Swimmer🏊‍♀️
Qian Sun -- Coder💻 | Blogger📝 | Swimmer🏊‍♀️

Комментарии