Java线程池实现原理总结

作者:负债程序猿 时间:2023-04-15 02:37:11 

要理解实现原理,必须把线程池的几个参数彻底搞懂,不要死记硬背

一、线程池参数

  • 1、corePoolSize(必填):核心线程数。

  • 2、maximumPoolSize(必填):最大线程数。

  • 3、keepAliveTime(必填):线程空闲时长。如果超过该时长,非核心线程就会被回收。

  • 4、unit(必填):指定keepAliveTime的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。

  • 5、workQueue(必填):任务队列。通过线程池的execute()方法提交的Runnable对象将存储在该队列中。

  • 6、threadFactory(可选):线程工厂。一般就用默认的。

  • 7、handler(可选):拒绝策略。当线程数达到最大线程数时就要执行饱和策略。

说下核心线程数和最大线程数的区别

拒绝策略可选值:

1、AbortPolicy(默认):放弃任务并抛出RejectedExecutionException异常。
2、CallerRunsPolicy:由调用线程处理该任务。
3、DiscardPolicy:放弃任务,但是不抛出异常。可以配合这种模式进行自定义的处理方式。
4、DiscardOldestPolicy:放弃队列最早的未处理任务,然后重新尝试执行任务。

二、线程池执行流程

上个流程图,先试着自己看下能不能看懂

Java线程池实现原理总结

简短的总结下线程池执行流程:

  • 1、一个任务提交到线程池后,如果当前的线程数没达到核心线程数,则新建一个线程并且执行新任务,注意一点,这个新任务执行完后,该线程不会被销毁;

  • 2、如果达到了,则判断任务队列满了没,如果没满,则将任务放入任务队列;

  • 3、如果满了,则判断当前线程数量是否达到最大线程数,如果没达到,则创建新线程来执行任务,注意,如果线程池中线程数量大于核心线程数,每当有线程超过了空闲时间,就会被销毁,直到线程数量不大于核心线程数;

  • 4、如果达到了最大线程数,并且任务队列满了,就会执行饱和策略;

三、四种现成的线程池

不想自己new线程池的话,可以用现成的

1、定长线程池(FixedThreadPool)

特点:只有核心线程,线程数量固定,执行完立即回收,任务队列为链表结构的有界队列。
应用场景:控制线程最大并发数

2、定时线程池(ScheduledThreadPool )

特点:核心线程数量固定,非核心线程数量无限,执行完闲置10ms后回收,任务队列为延时阻塞队列。
应用场景:执行定时或周期性的任务。

3、可缓存线程池(CachedThreadPool)

特点:无核心线程,非核心线程数量无限,执行完闲置60s后回收,任务队列为不存储元素的阻塞队列。
应用场景:执行大量、耗时少的任务。

4、单线程化线程池(SingleThreadExecutor)

特点:只有1个核心线程,无非核心线程,执行完立即回收,任务队列为链表结构的有界队列。
应用场景:不适合并发但可能引起IO阻塞性及影响UI线程响应的操作,如数据库操作、文件操作等。

上述四个线程池虽然方便,但是阿里巴巴规范明确说明不建议使用,因为可能会造成内存溢出,具体原因如下:

FixedThreadPoolSingleThreadExecutor:主要问题是堆积的请求处理队列均采用LinkedBlockingQueue,可能会耗费非常大的内存,严重的直接导致内存溢出。
CachedThreadPoolScheduledThreadPool:主要问题是它们的最大线程数是Integer.MAX_VALUE,可能会创建数量非常多的线程,严重的直接导致内存溢出。

来源:https://blog.csdn.net/qq_33709582/article/details/113614961

标签:Java,线程池,原理
0
投稿

猜你喜欢

  • springboot项目配置多个kafka的示例代码

    2023-11-23 23:15:29
  • Java数组(Array)最全汇总(上篇)

    2022-12-19 23:22:30
  • 深入理解C++中public、protected及private用法

    2023-07-02 11:30:17
  • SpringBoot访问静态资源的配置及顺序说明

    2022-07-18 13:53:31
  • java使double保留两位小数的多方法 java保留两位小数

    2023-06-17 14:01:30
  • Unity Shader实现玻璃材质效果

    2021-10-27 05:25:29
  • C#创建、部署、调用WebService图文实例详解

    2022-05-03 06:35:20
  • c#通过unicode编码判断字符是否为中文示例分享

    2022-01-13 16:33:44
  • 如何让Spring Rest 接口中路径参数可选

    2022-02-17 19:29:14
  • java反射之Method的invoke方法实现教程详解

    2023-07-09 20:24:36
  • Android RecyclerView使用ListAdapter高效刷新数据的操作方法

    2023-06-24 22:22:09
  • Java中notify和notifyAll的区别及何时使用

    2022-07-03 02:08:43
  • 在C#中使用二叉树实时计算海量用户积分排名的实现详解

    2023-05-15 07:51:12
  • Windows10 Java环境变量配置过程图解

    2022-12-16 15:08:38
  • java调用淘宝api联网查询ip归属地

    2022-06-11 12:21:20
  • springboot集成springsecurity 使用OAUTH2做权限管理的教程

    2023-12-22 22:57:21
  • java单例模式学习示例

    2022-03-29 19:03:41
  • Android入门教程之ListView的具体使用详解

    2022-02-12 06:35:59
  • 详解Spring/Spring boot异步任务编程WebAsyncTask

    2022-12-18 00:40:23
  • Android Studio设置主题与字体大小图文教程

    2023-05-25 15:54:10
  • asp之家 软件编程 m.aspxhome.com