ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

为什么阿里Java规约禁止使用Java内置线程池?

2019-08-04 13:50:54  阅读:296  来源: 互联网

标签:Java 规约 创建 线程 new pool ThreadPoolExecutor


IDEA导入阿里规约插件,当你这样写代码时,插件就会自动监测出来,并给你红线提醒。

告诉你手动创建线程池,效果会更好。

在探秘原因之前我们要先了解一下线程池 ThreadPoolExecutor 都有哪些参数及其意义。

ThreadPoolExecutor 构造方法:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        //code...      
}

 参数的意义:

1.corePoolSize 指定了线程池里的线程数量,核心线程池大小
2.maximumPoolSize 指定了线程池里的最大线程数量
3.keepAliveTime 当线程池线程数量大于corePoolSize时候,多出来的空闲线程,多长时间会被销毁。
4.unit 时间单位
5.workQueue 任务队列,用于存放提交但是尚未被执行的任务。
6.threadFactory 线程工厂,用于创建线程,一般可以用默认的
7.handler 拒绝策略,当任务过多时候,如何拒绝任务。当提交任务数超过maximumPoolSize + workQueue 的size之和,任务交给RejectedExecutionHandler 处理

 

阿里规约之所以强制要求手动创建线程池,也是和这些参数有关。具体为什么不允许,规约是这么说的:

线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

说明:Executors各个方法的弊端:
1)newFixedThreadPool和newSingleThreadExecutor:
  主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM。
2)newCachedThreadPool和newScheduledThreadPool:
  主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。

看一下这两种弊端怎么导致的。

第一种是因为,创建了一个size为Integer.MAX_VALUE的线程阻塞队列,可能会堆积大量的请求,消耗很大的内存,甚至导致OOM。

第二种是因为,创建了的线程池允许的最大线程数是Integer.MAX_VALUE,可能会创建大量的线程,消耗资源,甚至导致OOM。

这两种都是有点极端的,稍微点进去看一下源码就能看出来。

阿里规约提倡手动创建线程池,而非Java内置的线程池,给出的正例如下:

正例1:

//org.apache.commons.lang3.concurrent.BasicThreadFactory
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
    new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());

 

正例2:

ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();

//Common Thread Pool
ExecutorService pool = new ThreadPoolExecutor(5, 200,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());

pool.execute(()-> System.out.println(Thread.currentThread().getName()));
pool.shutdown();//gracefully shutdown

 

正例3:

<bean id="userThreadPool"
    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
  <property name="corePoolSize" value="10" />
  <property name="maxPoolSize" value="100" />
  <property name="queueCapacity" value="2000" />

  <property name="threadFactory" value= threadFactory />
  <property name="rejectedExecutionHandler">
    <ref local="rejectedExecutionHandler" />
  </property>
</bean>
//in code
userThreadPool.execute(thread);

 

---

关注公众号,编程大道,回复“手册”获取阿里Java开发手册最新版。

 

 


标签:Java,规约,创建,线程,new,pool,ThreadPoolExecutor
来源: https://www.cnblogs.com/ibigboy/p/11298004.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有