线程池参数详解及实际应用

背景:这两天接触一个使用线程池做异步任务的活,于是重新看了下线程池的参数配置,并结合项目本身给出合适的线程池配置。

一、线程池参数配置

主要参考下面这篇文章:https://blog.csdn.net/ye17186/article/details/89467919

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);

可以看出线程池主要有以上7个参数:分别是:

corePoolSize
maximumPoolSize
keepAliveTime
unit
workQueue
threadFactory
handler

线程池的主要工作方式是(1)首先由核心线程执行任务。(2)在核心线程不够的情况下将新来的任务加入到workQueue中等待被执行。(3)在workQueue加满之后如何还有新任务到达会创建新线程执行,直到线程池中线程数等于maximumPoolSize。(4)此时如果仍有大量任务进来导致workQueue满了就会执行handler拒绝策略。
我们重点看workQueue和handler。

二、workQueue

workQueue主要有一下四个实现。
①ArrayBlockingQueue

基于数组的有界阻塞队列,按FIFO排序。新任务进来后,会放到该队列的队尾,有界的数组可以防止资源耗尽问题。当线程池中线程数量达到corePoolSize后,再有新任务进来,则会将任务放入该队列的队尾,等待被调度。如果队列已经是满的,则创建一个新线程,如果线程数量已经达到maxPoolSize,则会执行拒绝策略。

②LinkedBlockingQuene

基于链表的无界阻塞队列(其实最大容量为Interger.MAX),按照FIFO排序。由于该队列的近似无界性,当线程池中线程数量达到corePoolSize后,再有新任务进来,会一直存入该队列,而不会去创建新线程直到maxPoolSize,因此使用该工作队列时,参数maxPoolSize其实是不起作用的

③SynchronousQuene

一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。

④PriorityBlockingQueue

具有优先级的无界阻塞队列,优先级通过参数Comparator实现。

三、拒绝策略

拒绝策略主要有下面4种
①CallerRunsPolicy

该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。
②AbortPolicy

该策略下,直接丢弃任务并抛出RejectedExecutionException异常
③DiscardPolicy

该策略下,直接丢弃任务,什么都不做。
④DiscardOldestPolicy

该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列。

四、实际场景

我刚好在做一个任务失败批量重试的功能,我们的项目部署CPU只有两核,并且根据前几次的经验,差不多每次失败任务数在300以内,任务成功后需要发送邮件给客户,根据这一场景我做了如下配置。

        ThreadPoolExecutor executor1=new ThreadPoolExecutor(2
                ,2
                ,60
                , TimeUnit.SECONDS
                ,new LinkedBlockingQueue<>()
                , new CallerBlocksPolicy(60));

这里只使用到两个核心线程,新的任务会加入到LinkedBlockingQueue中,Queue的大小为500。再队列满之后使用CallerBlocksPolicy策略让主线程发送邮件,确保任务不会丢失。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值