多线程的参数如何设置更合理?

163 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

1.线程池运行的基本原理

首先我们来了解下线程池的几个重要参数

  • int corePoolSize ,线程池中核心线程数,线程池内线程数小于 corePoolSize ,就会创建新线程,大于等于 corePoolSize ,这个任务就会保存到BlockingQueue,如果调用prestartAllCoreThreads()方法就会一次性的启动corePoolSize 个数的线程。
  • int maximumPoolSize,允许的最大线程数,当BlockingQueue也满了,并且线程池内线程数小于 maximumPoolSize时候就会再次创建新的线程
  • long keepAliveTime, 线程空闲下来后,存活的时间,这个参数只在线程池内线程数大于 corePoolSize才有用
  • TimeUnit unit,存活时间的单位值
  • BlockingQueue workQueue, 保存任务的阻塞队列
  • threadFactory, 创建线程的工厂,给新建的线程赋予名字
  • RejectedExecutionHandler handler :饱和策略

AbortPolicy :直接抛出异常,默认;

CallerRunsPolicy:用调用者所在的线程来执行任务

DiscardOldestPolicy:丢弃阻塞队列里最老的任务,队列里最靠前的任务

DiscardPolicy :当前任务直接丢弃

流程大致如下

01_线程池工作流程-9526433.png

2.那么我们如何设置线程参数更合理呢?

其实这主要看你的实际业务,是IO密集型,还是CPU密集型。

  • IO密集型,就是日常处理的任务,需要大量的读取数据,对磁盘、网络带宽的使用要求较高的任务,比如数据的下载、传输等等,此时对系统CPU的使用频率较低,对网卡、磁盘等设备使用率较高。比如mysql需要从磁盘家在数据到buffer pool,或者需要远程从网络上拉取一些文件等,都是IO密集型任务。

    特点:大量网络、文件操作

  • CPU密集型就是涉及到大量计算的场景,比如一些OLAP的数据库啥的,对服务器CPU使用频率是相当高的。

特点:大量的计算任务,CPU的使用率接近100%

那么针对上变得任务,线程数该如何去优化呢?

  • IO密集型:IO密集型的操作主要是处理IO的时间较长,这时候CPU处于空闲状态,明显,CPU的利用率还没达到更高,我们可以把最大线程数设置为核数的2倍,这样在一部分线程处理IO任务的时候,其他线程可以利用CPU处理其他事情。
  • CPU密集型:一般的话是设置最大线程数为CPU核数+1,这样可以最大利用CPU的资源,减少线程的上下文切换造成的性能损失。

这只是给的一点小建议,我们还是要根据自己业务的实际场景去调整优化。