温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java线程池实现原理是什么

发布时间:2022-01-21 17:07:44 来源:亿速云 阅读:208 作者:iii 栏目:开发技术

这篇文章主要讲解了“Java线程池实现原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java线程池实现原理是什么”吧!

一、线程池参数

  • 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:放弃队列最早的未处理任务,然后重新尝试执行任务。

二、线程池执行流程

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

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

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

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

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

三、四种现成的线程池

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

1、定长线程池(FixedThreadPool)

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

2、定时线程池(ScheduledThreadPool )

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

3、可缓存线程池(CachedThreadPool)

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

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

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

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

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

感谢各位的阅读,以上就是“Java线程池实现原理是什么”的内容了,经过本文的学习后,相信大家对Java线程池实现原理是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI