kim.zhang

风在前,无惧!


  • 首页

  • 标签42

  • 分类12

  • 归档94

  • 搜索

线程池.md

发表于 2020-08-10 更新于 2021-11-21 分类于 并发
本文字数: 2.1k 阅读时长 ≈ 2 分钟

1.为什么要使用线程池

  • 反复创建线程开销大
  • 过多的线程会占用太多内存

2.线程池的好处

  • 加快响应速度
  • 合理利用CPU和内存
  • 统一管理

3.线程池适用场景

  • 服务器接收到大量的请求时,使用线程池技术是非常合适的,它可以大大减少线程的创建和销毁次数,提高服务器的工作效率
  • 在开发中,如果需要创建5个以上的线程,就可以使用线程池来处理

4.线程池的参数

  • corePoolSize
    • 核心线程数,线程池在完成初始化后,默认情况下,线程池中并没有任何线程,线程池会等待有任务到来时再创建新线程去执行任务
  • maxPoolSize
    • 最大线程数,线程池有可能会在核心线程数的基础上,额外增加一些线程,但是这些新增加的线程数有一个上限
  • keepAliveTime
    • 如果线程池当前的线程数多于corePoolSize,那么如果多余的线程空闲时间超过keepAliveTime,它们就会被终止
  • ThreadFactory
    • 新的线程是由ThreadFactory创建的,默认使用Executors.defaultThreadFactory(),创建处理的线程都在同一个线程组,拥有统一的NORM_PRIORITY优先级并且都不是守护线程。如果自己指定ThreadFactory,那么就可以改变线程名、线程组、优先级、是否是守护线程等
    • 通常我们用默认的ThreadFactory就可以了
  • workQueue
    • 直接交换:SynchronousQueue
    • 无界队列:LinkedBlockingQueue
    • 有界队列:ArrayBlockingQueue

5.添加线程规则

  • 如果线程数小于corePoolSize,即使其他工作线程处于空闲状态,也会创建一个新线程来运行新任务
  • 如果线程数等于(或大于)corePoolSize但少于maxPoolSize,则将任务放入队列
  • 如果队列已满,并且线程数小于maxPoolSize,则创建一个新线程来运行任务
  • 如果队列已满,并且线程数大于maxPoolSize,则拒绝该线程

6.增减线程的特点

  • 如果设置corePoolSize和maxPoolSize相同,就可以创建固定大小的线程数
  • 线程池希望保持较少的线程数,并且只有在负载变得很大时才增加它
  • 通过设置maxPoolSize为很高的值,可以允许线程池容纳任意数量的并发任务
  • 如果使用的是无界队列(例如LinkedBolckingQueue),那么线程数就不会超过corePoolSize

7. 自带线程池介绍

  • newFixedThreadPool
    • 由于传进去的LinkedBlockingQueue是没有容量上限的,所以当请求数越来越多,并且无法及时处理完毕的时候,会容易造成占用大量的内存,可能会导致OOM
  • newSingleThreadPool
    • 和FixedThreadPool的原理基本一样,只不过把线程数直接设置成了1,所以这也会导致同样的问题,可能会占用大量的内存
  • newCacheThreadPool
    • 无界队列,可以自动回收多余的线程
    • maxPoolSize被设置为Integer.MAX_VALUE,这可能会创建数量非常多的线程,甚至导致OOM
  • newScheduledThreadPool
    • 支持定时以及周期性任务执行
newFixedThreadPool newSingleThreadPool newCacheThreadPool newScheduledThreadPool
corePoolSize 构造函数传参 1 0 构造方法传参
maxPoolSize 构造函数传参 1 Integer.MAX_VALUE Integer.MAX_VALUE
keepAliveTime 0 0 60 0
workQueue LinkedBlockingQueue LinkedBlockingQueue SynchrousQueue DelayedWorkQueue

8.线程池里的线程数量设定为多少比较合适

  • CPU密集型(加密,计算hash等):最佳线程数为CPU核心数1-2倍左右
  • 耗时IO型(读写数据库、文件、网络独写等):最佳线程数一般会大于cpu核心数很多倍
    • 线程数=CPU核心数*(1 + 平均等待时间/平均工作时间)

9.停止线程池的方法

  • shutdown:等待线程执行完毕后才终止
    • isShutdown:判断是否执行了shutDown方法
    • isTerminated:判断线程是否终止
  • awaitTermination:判断在指定时间内线程是否终止
  • shutDownNoe:立即终止线程,执行中的线程会被中断,队列中的线程会以List返回

10.线程池状态

  • RUNNING:接受新任务并处理排队任务
  • SHUTDOWN:不接受新任务,但处理排队任务
  • STOP:不接受新任务,也不处理排队任务,并中断正在进行的任务
  • TIDYING:所有任务都已终止,worderCount为零时,线程会转换到TIDYING状态,并将运行terminate()钩子方法
  • TERMINATED:terminate()运行完成

11.使用线程池需要注意的地方

  • 避免任务堆积
  • 避免线程数过度增加
  • 排查线程泄露(线程数量是否超出预期)
一毛也是爱~
Kim.Zhang 微信支付

微信支付

# JUC
锁的分类.md
并发队列.md
  • 文章目录
  • 站点概览
Kim.Zhang

Kim.Zhang

且行且珍惜
94 日志
12 分类
42 标签
E-Mail Weibo
  1. 1. 1.为什么要使用线程池
  2. 2. 2.线程池的好处
  3. 3. 3.线程池适用场景
  4. 4. 4.线程池的参数
  5. 5. 5.添加线程规则
  6. 6. 6.增减线程的特点
  7. 7. 7. 自带线程池介绍
  8. 8. 8.线程池里的线程数量设定为多少比较合适
  9. 9. 9.停止线程池的方法
  10. 10. 10.线程池状态
  11. 11. 11.使用线程池需要注意的地方
粵ICP备19091267号 © 2019 – 2022 Kim.Zhang | 629k | 9:32
本站总访问量 4 次 | 有 309 人看我的博客啦 |
博客全站共176.7k字
载入天数...载入时分秒...
0%