Java并发类库提供的线程池有哪几种? 分别有什么特点?

通常开发者都是利用 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算法,并行地处理任务,
不保证处理顺序。

我们从整体上把握一下各个类型的主要设计目的:

Executor 是一个基础的接口,其初衷是将任务提交和任务执行细节解耦,这一点可以体会其定义的唯一方法。

`void execute(Runnable command);`

ExecutorService 则更加完善,不仅提供 service 的管理功能,比如 shutdown 等方法,也
提供了更加全面的提交任务机制,如返回Future而不是 void 的 submit 方法。

  <T> Future<T> submit(Callable<T> task);

注意,这个例子输入的可是Callable,它解决了 Runnable 无法返回结果的困扰。

java 标准类库提供了几种基础实现,比如ThreadPoolExecutor、
ScheduledThreadPoolExecutor、ForkJoinPool。这些线程池的设计特点在于其高度的可调
节性和灵活性,以尽量满足复杂多变的实际应用场景,我会进一步分析其构建部分的源码,剖析这种灵活性的源头。

Executors 则从简化使用的角度,为我们提供了各种方便的静态工厂方法。

全部评论

相关推荐

10-14 23:01
已编辑
中国地质大学(武汉) Java
CUG芝士圈:虽然是网上的项目,但最好还是包装一下,然后现在大部分公司都在忙校招,十月底、十一月初会好找一些。最后,boss才沟通100家,别焦虑,我去年暑假找第一段实习的时候沟通了500➕才有面试,校友加油
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务