Java核心技术36讲之(二十一)ava并发类库提供的线程池有哪几种? 分别有什么特点?

通常开发者都是利用 Executors 提供的通用线程池创建方法,去创建不同配置的线程池,主要区别在于不同的 ExecutorService 类型或者不同的初始参数。

Executors 目前提供了 5 种不同的线程池创建配置:

● newCachedThreadPool(),它是一种用来处理大量短时间工作任务的线程池,具有几个鲜明特点:它会试图缓存线程并重用,当无缓存线程可用时,就会创建新的工作线程;如果线程闲置的时间超过 60 秒,则被终止并移出缓存;长时间闲置时,这种线程池,不会消耗什么资源。其内部使用 SynchronousQueue 作为工作队列。

● newFixedThreadPool(int nThreads),重用指定数目(nThreads)的线程,其背后使用的是无界的工作队列,任何时候最多有 nThreads 个工作线程是活动的。这意味着,如果任务数量超过了活动队列数目,将在工作队列中等待空闲线程出现;如果有工作线程退出,将会有新的工作线程被创建,以补足指定的数目 nThreads。

● newSingleThreadExecutor(),它创建的是个 ScheduledExecutorService,也就是可以进行定时或周期性的工作调度。工作线程数目被限制为 1,所以它保证了所有任务的都是被顺序执行,最多会有一个任务处于活动状态,并且不允许使用者改动线程池实例,因此可以避免其改变线程数目。

● newScheduledThreadPool(int corePoolSize),同样是 ScheduledExecutorService,区别在于它会保持 corePoolSize 个工作线程。

● newWorkStealingPool(int parallelism),这是一个经常被人忽略的线程池,Java 8 才加入这个创建方法,其内部会构建ForkJoinPool,利用Work-Stealing算法,并行地处理任务,不保证处理顺序。


线程池虽然为提供了非常强大、方便的功能,但是也不是银弹,使用不当同样会导致问题。我这里介绍些典型情况,经过前面的分析,很多方面可以自然的推导出来。

● 避免任务堆积。前面我说过 newFixedThreadPool 是创建指定数目的线程,但是其工作队列是无界的,如果工作线程数目太少,导致处理跟不上入队的速度,这就很有可能占用大量系统内存,甚至是出现 OOM。诊断时,你可以使用 jmap 之类的工具,查看是否有大量的任务对象入队。

● 避免过度扩展线程。我们通常在处理大量短时任务时,使用缓存的线程池,比如在最新的 HTTP/2 client API 中,目前的默认实现就是如此。我们在创建线程池的时候,并不能准确预计任务压力有多大、数据特征是什么样子(大部分请求是 1K 、100K 还是 1M 以上?),所以很难明确设定一个线程数目。

● 另外,如果线程数目不断增长(可以使用 jstack 等工具检查),也需要警惕另外一种可能性,就是线程泄漏,这种情况往往是因为任务逻辑有问题,导致工作线程迟迟不能被释放。建议你排查下线程栈,很有可能多个线程都是卡在近似的代码处。

● 避免死锁等同步问题,对于死锁的场景和排查,你可以复习专栏第 18 讲。

● 尽量避免在使用线程池时操作 ThreadLocal,同样是专栏第 17 讲已经分析过的,通过今天的线程池学习,应该更能理解其原因,工作线程的生命周期通常都会超过任务的生命周期。


线程池大小的选择策略

上面我已经介绍过,线程池大小不合适,太多会太少,都会导致麻烦,所以我们需要去考虑一个合适的线程池大小。虽然不能完全确定,但是有一些相对普适的规则和思路。
● 如果我们的任务主要是进行计算,那么就意味着 CPU 的处理能力是稀缺的资源,我们能够通过大量增加线程数提高计算能力吗?往往是不能的,如果线程太多,反倒可能导致大量的上下文切换开销。所以,这种情况下,通常建议按照 CPU 核的数目 N 或者 N+1。
● 如果是需要较多等待的任务,例如 I/O 操作比较多,可以参考 Brain Goetz 推荐的计算方法:
● 线程数 = CPU 核数 × (1 + 平均等待时间 / 平均工作时间)
这些时间并不能精准预计,需要根据采样或者概要分析等方式进行计算,然后在实际中验证和调整。
●上面是仅仅考虑了 CPU 等限制,实际还可能受各种系统资源限制影响,例如我最近就在 Mac OS X 上遇到了大负载时ephemeral 端口受限的情况。当然,我是通过扩大可用端口范围解决的,如果我们不能调整资源的容量,那么就只能限制工作线程的数目了。这里的资源可以是文件句柄、内存等。

猜你喜欢

转载自blog.csdn.net/lwl2014100338/article/details/80787492