Java线程池内存模型与参数
Posted Lost In Life
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java线程池内存模型与参数相关的知识,希望对你有一定的参考价值。
我们创建线程的常见方式一般有继承Thread类以及实现Runnable接口,其实Thread类也是实现了Runnable接口。通过这两种方式创建的线程,在执行完毕之后都会被销毁,这样频繁的创建和销毁线程是一件很浪费资源到的事情。那么,有没有什么办法解决这个问题呢?通过创建线程池就可以解决这个问题。
Tomcat的线程模型与如下所述的原理类似
通过线程池创建的线程执行完毕之后并不会销毁,而是会回到线程池继续重复利用,执行其他任务。
线程池内存模型如图所示:
一、核心参数
corePoolSize(核心线程数)
(1)核心线程会一直存在,即使没有任务执行;
(2)当线程数小于核心线程数的时候,即使有空闲线程,也会一直创建线程直到达到核心线程数;
(3)设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭。
queueCapacity(任务队列容量)
也叫阻塞队列,当核心线程都在运行,此时再有任务进来,会进入任务队列,排队等待线程执行。
maxPoolSize(最大线程数)
(1)线程池里允许存在的最大线程数量;
(2)当任务队列已满,且线程数量大于等于核心线程数时,会创建新的线程执行任务;
(3)线程池里允许存在的最大线程数量。当任务队列已满,且线程数量大于等于核心线程数时,会创建新的线程执行任务。
keepAliveTime(线程空闲时间)
(1)当线程空闲时间达到keepAliveTime时,线程会退出(关闭),直到线程数等于核心线程数;
(2)如果设置了allowCoreThreadTimeout=true,则线程会退出直到线程数等于零。
allowCoreThreadTimeout(允许核心线程超时)
rejectedExecutionHandler(任务拒绝处理器)
(1)当线程数量达到最大线程数,且任务队列已满时,会拒绝任务;
(2)调用线程池shutdown()方法后,会等待执行完线程池的任务之后,再shutdown()。如果在调用了shutdown()方法和线程池真正shutdown()之间提交任务,会拒绝新任务。
二、线程池参数默认值
corePoolSize = 1
queueCapacity = Integer.MAX_VALUE
maxPoolSize = Integer.MAX_VALUE
keepAliveTime = 60秒
allowCoreThreadTimeout = false
rejectedExecutionHandler = AbortPolicy()
三、ThreadPoolExecutor(线程池)执行顺序
当线程数小于核心线程数时,会一直创建线程直到线程数等于核心线程数;
当线程数等于核心线程数时,新加入的任务会被放到任务队列等待执行;
当任务队列已满,又有新的任务时,会创建线程直到线程数量等于最大线程数;
当线程数等于最大线程数,且任务队列已满时,新加入任务会被拒绝。
附:使用示例
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
/**
corePoolSize: 线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
keepAliveTime: 线程池维护线程所允许的空闲时间
unit: 线程池维护线程所允许的空闲时间的单位
workQueue: 线程池所使用的缓冲队列
handler: 线程池对拒绝任务的处理策略
*/
// 启动示例:
ThreadPoolExecutor epool = new ThreadPoolExecutor(8, 8, 0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(100000),
new ThreadPoolExecutor.CallerRunsPolicy());
总结Q/A:
Q. 线程池是什么时候创建线程的?
A.任务提交的时候(核心线程也并非系统启动就创建!)
Q.任务runnable task是先放到core到maxThread之间的线程,还是先放到队列?
A.先放队列!!!
Q. 队列中的任务是什么时候取出来的?
A. worker中 runWorker() 一个任务完成后,会取下一个任务
Q. 什么时候会触发reject策略?
A.队列满并且maxthread也满了, 还有新任务,默认策略是reject
Q. core到maxThread之间的线程什么时候会die?
A. 没有任务时,或者抛异常时。
core线程也会die的,core到maxThread之间的线程有可能会晋升到core线程区间,
core max只是个计数,线程并不是创建后就固定在一个区间了
Q. task抛出异常,线程池中这个work thread还能运行其他任务吗?
A. 不能。 但是会创建新的线程, 新线程可以运行其他task。
---------------------
参考链接:
https://blog.csdn.net/qq_42815754/article/details/84669545
https://www.cnblogs.com/yszzu/p/10122658.html
以上是关于Java线程池内存模型与参数的主要内容,如果未能解决你的问题,请参考以下文章