java线程池 内存_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 workQueue,RejectedExecutionHandler handler)/**corePoolSize: 线程池维护线程的最少数量maximumPoolSize:线程池维护线程的最大数量keepAliveTime: 线程池维护线程所允许的空闲时间unit: 线程池维护线程所允许的空闲时间的单位workQueue: 线程池所使用的缓冲队列handler: 线程池对拒绝任务的处理策略*/// 启动示例:ThreadPoolExecutor epool = new ThreadPoolExecutor(8, 8, 0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue(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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值