Advertisement

Java多场景需求使用各自独立线程池还是共用一个线程池?

阅读量:

在Java项目开发中经常调用线程池来处理各种任务需求。当我们面临多种任务场景时是为每个场景单独配置一个线程池还是共享同一个线程池?这个问题确实值得商榷。

一、建议

这里我们建议:如果你的Java项目涉及多个不同场景需要使用线程池,则推荐每个业务场景独自配备独立线程池,并避免所有场景共享同一套线程池。

二、原因分析

各条独立线城池之间各自完成各自的任务作业,在不影响彼此的情况下能够更好地保障本任务的整体运行效率与系统稳定性

2)如果所有的场景共用一个线程池,可能会出现如下问题,举例:

比如有任务A、任务B、任务C 这三个任务场景共用一个线程池,配置如下:

复制代码
    threadPool:
      corePoolSize: 10
      maximumPoolSize : 1000
      workQueue : 1000
      keepAliveSeconds: 300
    
    
    java

说明:如需了解这些线程池参数的具体含义,请参考Java创建线程池的几种方式具体实现中有关ThreadPoolExecutor线程池类7大参数含义的详解部分。

想象一种情况:当task C的请求数量急剧上升时会耗尽整个线程池的所有资源导致task A与task B无法获得任何可用的线程从而出现长时间无法获取资源的状态。例如当task C同时接收200个请求时这种情况就可能出现/task A与(task B)几乎得不到任何资源或者只能分配到极少量的资源/在这种情况下如果task C中的每一个子进程所需的时间极其漫长那么task A与(task B)基本上都会长时间处于等待状态

所以为了避免这种情况的产生,最好的方式是建立独立的线程池

无论任务C的线程是否发生堵塞或其他问题都不会影响到任务A和任务B的执行;同样地,在确保这种机制下,任务A和任务B也不会干扰到其他业务场景的任务处理。

每个任务场景下的线程通常建议为该特定业务逻辑分配独立的名称标签(Thread ID),这有助于方便在出现问题时快速定位到具体的进程日志信息。为了确保各个业务场景之间线程名称与功能模块之间的清晰对应关系(Correspondence),建议为不同场景配置独立的线程池(Thread Pool),并确保该 Thread ID 与相应的业务逻辑模块之间具有明确的一一映射关系(Mapping)。

三、总结

针对Java的多场景任务需求而言, 建议采用各自独立的线程池配置方案. 其中一部分可能源自JDK内部预先定义的部分功能模块;另一部分也可能由第三方jar包提供支持;基于特定的应用场景进行定制配置可以更好地满足开发需求;同时单独针对不同业务场景定制化的线程池也为该方案提供了更高的灵活性.

肯定是多个线程池:

JDK自带的各种类大量采用了多种并行计算相关的功能模块。
许多开源框架普遍采用了丰富的资源管理与调度机制配置。
个人应用系统通常会根据需求构建多个独立的资源管理组件。
不必要考虑什么CPU密集型任务还是I/O密集型任务(这不是一种不切实际的观点,在Java语言学习中无需关注I/O还是CPU密集型的任务)。
建议根据具体业务需求确定合适的资源管理组件数量及每个组件的具体参数,并通过充分测试确保性能稳定。不同业务场景下的系统架构可能对资源分配有不同的要求。

一台服务器的硬件配置固定,例如拥有20个核心和40个线程的CPU,尽可能地部署一个应用,避免过度配置(除了Tomcat之外的应用)

经过测试你会发现:

  1. 有时过多地创建线程会导致内存占用显著增加
  2. 在创建1个、5个或10个线程时,处理数据的性能表现相近;因此不宜过度增加线程数量
  3. 针对线程池相关的问题,在长时间内进行持续测试,并不断优化调整参数设置才能最终提供符合当前需求的一套有效解决方案。

全部评论 (0)

还没有任何评论哟~