线程池-ThreadPoolExecutor

一、线程池是什么

一般来说,线程池是一种池化技术的实现,通过一个或者多个线程来执行用户提交的任务,解决了每执行一个任务就创建一个线程造成的资源浪费问题,同时也提供了很多对线程进行管理的操作方法,比如停止一个线程或者统计已经完成的任务量等等。

  • 类结构


    image.png

从类的结构图中看到,ThreadPoolExecutor实现了Executor以及ExecutorService的接口
1、Executor:Executor提供了execute()接口,ThreadPoolExecutor对其进行了实现
2、ExecutorService:ExecutorService定义了shutdown()、submit()等接口,主要作用是对线程池状态的控制以及定义任务提交的方式
3、AbstractExecutorService:AbstractExecuorService是模板方法设计模式的实现,提供了ExecutorService接口的默认实现,提供线程池通用的逻辑能力,比如submit()方法

二、类参数

image.png
  • 阻塞队列
image.png
  1. ArrayBlockingQueue

    image.png

  2. LinkedBlockingQueue

    image.png

  3. DelayQueue

    image.png

  4. SynchronousQueue
    可以简单的理解为:如果要往队列放元素必须要有另一个线程想从队列中取元素,没有现场要取你就放不进去

    image.png

  5. TransferQueue
    TransferQueue可以理解为SynchronousQueue的加强版,比如公平锁,按请求先后顺序进行处理

    image.png

  6. PriorityBlockingQueue

    image.png

  • 拒绝策略
image.png
  1. DiscardOldestPolicy 丢弃队列中第一个任务
  2. AbortPolicy 抛异常
  3. CallerRunsPolicy 交给提交过来的线程去执行
  4. DiscardPolicy 丢弃,不做任何操作

三、线程池类型

  1. newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理所需,可灵活回收空闲线程,若线程数不够,则新建线程。

  2. newFixedThreadPool:创建一个固定大小的线程池。可控制并发的线程数量,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。

  3. newSingleThreadExecutor:创建一个单线程的线程池,即只创建唯一的工作者线程来执行任务,,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

  4. newScheduleThreadPool:创建一个定长的线程池,支持定时及周期性任务执行。


    image.png

四、踩坑经历

  1. 工作中,很多小伙伴使用newCachedThreadPool新建线程池,这个线程池的最大线程数是Integer.Max值,正常情况下,是会导致线程池线程太多,耗尽服务器资源导致性能问题,所以使用时考虑清楚
  2. newFixedThreadPool,任务队列大小可达Integer.Max,正常情况任务堆积过多绝对导致OOM,已经目测过两次
  3. 如果线程池中的任务队列大小在业务发展过程中不会很大,可以使用线程池,不过一般我建议使用MQ,原因有两个:一是如果发生重启或者服务器宕机,队列中的任务就会丢失,二是很难控制队列中的任务不会过大,而MQ会自动帮我们保存消息
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容