首页 > 其他分享 >为什么不建议或不能用Executor去创建线程池?

为什么不建议或不能用Executor去创建线程池?

时间:2023-08-06 13:34:31浏览次数:46  
标签:Executors OOM 创建 Executor VALUE 线程 MAX Integer

答:会存在内存溢出的风险。因为Executors中的核心方法,默认创建线程池的最大线程数是Integer.MAX_VALUE即int类型的最大值2^32-1,最大线程数允许这么多,几乎相当于不限制线程数,而这样的后果就是,如果瞬间请求量非常大,如果达到这个上限,没有任何服务器能够继续工作,肯定会抛出OOM异常。

Executors核心的方法有五个:

1)Executors.newCachedThreadPool

这个方法中maximumPoolSize最大可以至Integer.MAX_VALUE,是高度可伸缩的线程池,如果达到这个上限,相信没有任何服务器能够继续工作,肯定会抛出OOM异常。keepAliveTime默认为60秒,工作线程处于空闲状态,则回收工作线程。如果任务数量增加,再次创建出新线程处理任务。

2)Executors.newScheduledThreadPool

这个方法中maximumPoolSize最大可以至Integer.MAX_VALUE,也是是高度可伸缩的线程池,同样存在OOM问题。

它支持定时以及周期性的执行任务,它与newCachedThreadPool的区别是不回收工作线程。

3)Executors.newSingleThreadExecutor

作用:创建一个单线程的线程池,相当于单线程串行执行所有任务,保证按任务的提交顺序依次执行。当瞬间请求量非常大也会存在OOM问题。

4)Executors.newFixedThreadPool

输入的参数即是固定线程数,既是核心线程数也是最大线程数,不存在空闲线程,所以keepAliveTime等于0

 这里,输入的队列没有指明长度,其中LinkedBlockingQueue的构造方法:

 LinkedBlockingQueue是无界队列,最大长度也是Integer.MAX_VALUE即int类型的最大值2^32-1,使用这样的无界队列,如果瞬间请求量非常大,会有OOM风险。

5)Executors.newWorkStealingPool

JDK8引入的,作用:创建持有足够线程的线程池支持给定的并行度,并通过使用多个队列减少竞争,此构造方法中把CPU数量设置为默认的并行度:

禁止直接使用Executors创建线程池原因:
Executors.newCachedThreadPool和Executors.newScheduledThreadPool两个方法最大线程数为Integer.MAX_VALUE,如果达到上限,没有任务服务器可以继续工作,肯定会抛出OOM异常。
Executors.newSingleThreadExecutor和Executors.newFixedThreadPool两个方法的workQueue参数为new LinkedBlockingQueue<Runnable>(),容量为Integer.MAX_VALUE,如果瞬间请求非常大,会有OOM风险。
总结:以上5个核心方法除
Executors.newWorkStealingPool方法之外,其他方法都有OOM风险。

    参考: 阿里巴巴Java开发手册推荐线程池的创建方式 - 简书 (jianshu.com) 多线程高并发(五)线程池_newworkstealingpool有没有oom的情况_解决问题no解决代码问题的博客-CSDN博客

标签:Executors,OOM,创建,Executor,VALUE,线程,MAX,Integer
From: https://www.cnblogs.com/cdlyy/p/17609175.html

相关文章

  • 创建usr local mysql在home下
    ln-s目录软链接名称......
  • linux修改线程数
    vim/etc/security/limits.d/90-nproc.conf查看核心线程数量ulimit-u......
  • 进程与线程
        ......
  • 前端学习笔记202304学习笔记第十九天-vue3.0-vue2的项目中创建路由2
      ......
  • 记录小知识 数据库设置自动填充更新创建字段时间
    1,在数据库中设置该字段类型为timestamp  2,设置默认值为 CURRENT_TIMESTAMP3,更新字段需要点击勾选根据当前时间戳更新 而创建时间是不需要勾选的因为创建只需要一次 ......
  • 记录小知识 springboot,maven创建的多模块 子模块无法使用父类版本
    使用依赖时发现依赖有问题,回来检查发现没有加springboot父工程检查父模块是否加入父标签:只需要在父模块中添加一次就可以了<parent><groupId>org.springframework.boot</groupId><cartifactId>spring-boot-starter-parent</artifactId><version>2.1.3.RELE......
  • 第二章进程和线程
    2.1任务在操作系统层面,任务常常时代表进程的,比如windows是典型的多任务操作系统,指系统中可以同时运行多个进程。在CPU手册中,很多时候是使用"任务"来代之线程的,比如著名的多任务状态段(TaskStateSegmentTSS).就是用来记录每个线程的状态。CPU一级的任务很多时候相当于进......
  • 对线程join()方法的理解
    java线程的join()方法的理解thread.join()把指定的线程加入到当前线程,可以将两个交替执行的线程和并为顺序执行的线程。简单说就是同步。例1:比如在线程B中调用了线程A的join方法,直到线程A执行完毕后,才会继续执行线程B。例2:再比如我们做查询操作,总任务需要返回三个查询列......
  • 使用 VirtualBox+Vagrant 创建 CentOS7 虚拟机
    一、准备工作1.1软件下载VirtualBox:Downloads–OracleVMVirtualBoxVagrant:Install|Vagrant|HashiCorpDeveloper1.2软件安装安装VirtualBox-7.0.10-158379-Win.exe安装vagrant_2.3.7_windows_amd64.msiNotes:安装目录记得修改下,默认安装在C盘。......
  • Java多线程-龟兔赛跑
    Java多线程-龟兔赛跑packagecom.alibaba;publicclassTestThread003implementsRunnable{privateStringwinner;@Overridepublicvoidrun(){for(inti=0;i<=100;i++){booleanflag=getWinner(i);if(flag){......