java线程池相关问题

线程池参数

  1. corePoolSize 核心线程池大小----10
  2. maximumPoolSize 最大线程池大小----30
  3. keepAliveTime 线程池中超过corePoolSize数目的空闲线程最大存活时间----30+
  4. 单位TimeUnit TimeUnit keepAliveTime时间单位----TimeUnit.MINUTES
  5. workQueue 阻塞队列----new ArrayBlockingQueue(10)====10容量的阻塞队列 ,LinkedBlockingQueue:最大容量是Integer.MAX_VALUE
  6. threadFactory 新建线程工厂----new CustomThreadFactory()====定制的线程工厂
  7. rejectedExecutionHandler 当提交任务数超过maxmumPoolSize+workQueue之和时, 即当提交第41个任务时(前面线程都没有执行完,此测试方法中用sleep(100)), 任务会交给RejectedExecutionHandler来处理

线程池线程提交策略

  1. 当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
  2. 当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
  3. 当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务
  4. 当提交任务数超过maximumPoolSize时,新提交任务,使用拒绝策略RejectedExecutionHandler处理满了的任务,默认是AbortPolicy
  5. 当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程
  6. 当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭

线程池的拒绝策略

当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:

  1. ThreadPoolExecutor.AbortPolicy : 丢弃任务并抛出RejectedExecutionException异常。 默认策略

  2. ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。

  3. ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)

  4. ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

几种常用线程池,以及可能发生的问题:

SingleThreadPool 介绍

ExecutorService scheduledThreadPool = Executors.newSingleThreadExecutor();   
//SingleThreadExecutor实现方式
new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());

单个线程的线程池,使用唯一的工作线程来执行任务。保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

FixedThreadPool介绍

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);        
//FixedThreadPool实现方式
new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
  • 定长线程池,corePoolSize=maximumPoolSize
  • 可指定线程池大小,可控制线程最大并发数
  • 超出的线程会被提交到工作队列中(LinkedBlockedQueue 最大长度Integer.MAX_VALUE)

SingleThreadPool 和FixedThreadPool可能出现的问题

线程数目固定,满了之后再提交,允许请求的最大线程数为,可能会堆积大量请求导致OOM

CachedThreadPool 介绍

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();           
//newCachedThreadPool实现方式
new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
  • 可缓存线程池,自动回收空闲线程
  • 当线程池中的线程空闲时间超过60s,便会终止该空闲线程并从缓存线程池中移除
  • 超出maximumPoolSize的线程会创建新的线程

ScheduledThreadPool介绍

ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);   
//scheduledThreadPool 实现方式
new ThreadPoolExecutor(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue());
  • 大小无限制的线程池,支持定时和周期性的执行线程
  • 最大线程数Integer.MAX_VALUE

CachedThreadPool 和 scheduledThreadPool

会直接创建新的线程,最大线程数为Integer.Max_value,可能会创建大量的线程从而导致OOM

使用线程池的建议

如何设置线程池大小?

  • 高并发、任务执行时间较短的业务:线程数设置为CPU核数+1
  • 低并发、IO操作密集的业务:线程数可设置的较大些
  • 低并发、计算型的业务:线程数设置为CPU核数+1
  • 高并发、任务时间长的业务:可利用缓存或者中间件来对任务进行拆分或解耦

使用线程池的好处

  • 减少了创建和销毁线程的时间
  • 控制线程的最大并发数
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值