ITPub博客

首页 > 数据库 > 数据库开发技术 > 你会用线程池吗?

你会用线程池吗?

原创 数据库开发技术 作者:毛毛小妖的笔记 时间:2019-07-02 23:00:00 0 删除 编辑

        随着项目的复杂度越来越高,很多地方都会用到多线程。而在多线程领域呢,我们经常使用的就是线程池啦。一提到线程池,小伙伴们兴高采烈的说,不就是调用那几个jdk自带的方法吗,so easy。那你就大错特错啦,如果你平时都是这么用的话,那么你一定没有阅读源码的好习惯,那推荐的用法是什么呢?那下面就来详细的说说吧。

大家看过源码都知道,jdk自带的这四个方法,底层使用的是LinkedBlockingQueue,虽然设置了最大线程数,但是设置的值为Integer.MAX_VALUE,这个数字是相当可怕的,也就相当于是无界队列,当请求比较多时,容易堆积在阻塞队列中,引发OOM。这个是最根本的原因,当然了,阿里巴巴编码规范中也明确的规定了不要使用jdk自带的这四个方法。而推荐的做法是使用ThreadPoolExecutor的构造方法,就是下面这个啦:

  1. public ThreadPoolExecutor(int corePoolSize,

  2. int maximumPoolSize,

  3. long keepAliveTime,

  4. TimeUnit unit,

  5. BlockingQueue<Runnable> workQueue,

  6. ThreadFactory threadFactory,

  7. RejectedExecutionHandler handler)

我们来详细看一下这几个参数:

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

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

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

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

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

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

知道这几个参数的含义当然是不够的了,我们在使用的时候主要关心的是最大线程数,那具体怎么来设置最大线程数呢?这个就跟你们的机器有关啦,在java代码中获取机器核心数的代码是

  1. Runtime.getRuntime().availableProcessors();

通过这行代码,我们就可以知道当前项目运行的机器的核心是多少啦。接下来我们要讨论如何设置啦。首先我们要分两种情况,即CPU密集型和IO密集型任务。

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

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

原文作者:毛毛小妖的笔记;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2019-04-04

  • 博文量
    70
  • 访问量
    46581