月眸


线程池—合理设置线程池大小

毛毛小妖 2019-06-28 240浏览 0条评论
首页/ 正文
分享到: / / / /

平时我们在项目中使用多线程时,建议不要使用jdk自带的四个创建线程池的方法:newCachedThreadPool,newFixedThreadPool,newSingleThreadExecutor,newScheduledThreadPool。这也是阿里巴巴编码规范要求的,因为这些方法使用的是无界队列,当请求比较多时,容易堆积在阻塞队列中,引发OOM。所以我们要使用下面这个构造方法来创建线程池:

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

这个构造方法的参数我在另外一篇文章中(线程池—jdk提供的四种创建线程池的方法)已经详细介绍过了。这里再简单说一下:

corePoolSize:核心线程数。核心线程会一直存在,即使没有任务执行;当线程数小于核心线程数的时候,即使有空闲线程,也会一直创建线程直到达到核心线程数;通常设置为1就可以了。

maxPoolSize:最大线程数。是线程池里允许存在的最大线程数量;

keepAliveTime:线程空闲时间。当线程空闲时间达到keepAliveTime时,线程会退出(关闭),直到线程数等于核心线程数。

workQueue:阻塞队列。建议使用有界队列,比如ArrayBlockingQueue

ThreadFactory:线程创建工厂。一般用来设置线程名称的。

handler:拒绝策略。一般用来做日志记录等。

重点来啦:

我们说设置线程池大小,主要是设置最大线程的数量,即maxPoolSize参数的大小。那这个应该设置成多少合适呢?首先我们要分两种情况,即CPU密集型和IO密集型任务。

CPU密集型任务:即需要大量计算的任务,因为计算是由CPU来完成的,所以称之为CPU密集型任务。这个时候设置为CPU核心数+1就可以了。

IO密集型任务:即需要通过网络来交互的任务,通常是指数据库数据交互、文件上传下载、网络数据传输等任务。这个时候需要设置为CPU核心数*2。但是实际情况中可以通过自己的测试来设置合理的数值,通过与大牛的交流得知,这个数值可以设置为CPU核心数/(1-阻塞系数),阻塞系数一般在0.8~0.9之间。比如8核CPU可以设置为:8*(1-0.9)=80。

注意:在java中获取CPU核心数可以用以下代码:

Runtime.getRuntime().availableProcessors();

 

最后修改:2019-06-28 09:50:13 © 著作权归作者所有
如果觉得我的文章对你有用,请随意赞赏
扫一扫支付

上一篇

发表评论

说点什么吧~

评论列表

还没有人评论哦~赶快抢占沙发吧~