Java线程池

线程池作用:限制系统中执行线程的数量
为什么要用线程池:
1、减少了创建和销毁线程的次数,每个工作线程都可以被重复使用,可执行多个任务
2、可以根据系统的承受能力,调整线程池中工作线程的数量,防止因为消耗过多的内存

Java原生线程池
ThreadPoolTaskExecutor
*
* step1.调用ThreadPoolExecutor的execute提交线程,首先检查CorePool,如果CorePool内的线程小于CorePoolSize,新创建线程执行任务。
* step2.如果当前CorePool内的线程大于等于CorePoolSize,那么将线程加入到BlockingQueue。
* step3.如果不能加入BlockingQueue,在小于MaxPoolSize的情况下创建线程执行任务。
* step4.如果线程数大于等于MaxPoolSize,那么执行拒绝策略。
*
* corePoolSize 核心线程池大小
* maximumPoolSize 线程池最大容量大小
* keepAliveTime 线程池空闲时,线程存活的时间
* TimeUnit 时间单位
* ThreadFactory 线程工厂
* BlockingQueue任务队列
* RejectedExecutionHandler 线程拒绝策略

  • Spring中SpringFrameWork 的 ThreadPoolTaskExecutor ,是辅助JDK的ThreadPoolExecutor的工具类,它将属性通过 JavaBeans 的命名规则提供出来,方便进行配置。

Java Executors
CachedThreadPool 缓存线程池
FixedThreadPool 定长线程池 可控制线程最大并发数
ScheduledThreadPool 定长线程池,支持定时及周期性执行
SingleThreadPool 单线程化线程池
FixedThreadPool 与 SingleThreadPool 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。
CachedThreadPool 与 SingleThreadPool 允许创建的线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。

线程池里面到底该设置多少个线程呢?
http://swiftlet.net/archives/3012
基本原则是:应用程序的最小线程数应该等于可用的处理器核数。具体场景又分为以下两种情况:
(1)如果所有的任务都是计算密集型的,则创建处理器可用核心数那么多个线程就可以了。在这种情况下,创建更多的线程对程序性能而言反而是不利的。因为当有多个任务处于就绪状态时,处理器核心需要在线程间频繁进行上下文切换,而这种切换对程序性能损耗较大。
(2)如果任务都是IO密集型的,那么我们就需要开更多的线程来提高性能。当一个任务执行IO操作时,其线程将被阻塞,于是处理器可以立即进行上下文切换以便处理其他就绪线程。如果我们只有处理器可用核心数那么多个线程的话,即使有待执行的任务也无法处理,因为我们已经拿不出更多的线程供处理器调度了。
总之,如果任务有50%的时间处于阻塞状态,则程序所需线程数为处理器可用核心数的两倍。如果任务被阻塞的时间少于50%,即这些任务是计算密集型的,则程序所需线程数将随之减少,但最少也不应低于处理器的核心数。如果任务被阻塞的时间大于执行时间,即该任务是IO密集型的,我们就需要创建比处理器核心数大几倍数量的线程。计算出程序所需线程的总数的公式如下:

线程数=CPU可用核心数/(1-阻塞系数),其中阻塞系数的取值在0和1之间。

计算密集型任务的阻塞系数为0,而IO密集型任务的阻塞系数则接近1。一个完全阻塞的任务是注定要挂掉的,所以我们无须担心阻塞系数会达到1。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值