ThreadPoolTaskExecutor和ThreadPoolExecutor区别

1.ThreadPoolTaskExecutor和ThreadPoolExecutor区别

ThreadPoolTaskExecutor是spring core包中的,而ThreadPoolExecutor是JDK中的JUC。

ThreadPoolTaskExecutor是对ThreadPoolExecutor进行了封装处理。

ThreadPoolExecutor结构,祖类都是调用Executor接口:

ThreadPoolTaskExecutor结构,祖类都是调用Executor接口:

在这里插入图片描述

2.工具类 : Executors 

Executors为线程池工具类,相当于一个工厂类,用来创建合适的线程池,返回ExecutorService类型的线程池。有如下方法:

ExecutorService newFixedThreadPool() : 创建固定大小的线程池


ExecutorService newCachedThreadPool() : 缓存线程池,线程池的数量不固定,可以根据需求自动的更改数量。


ExecutorService newSingleThreadExecutor() : 创建单个线程池。 线程池中只有一个线程

ScheduledExecutorService newScheduledThreadPool() : 创建可以执行延迟或定时任务的线程池
 

3.ThreadPoolTaskExecutor和ThreadPoolExecutor以及Executors到底该使用哪个?

ThreadPoolTaskExecutor和ThreadPoolExecutor比Executors创建线程池更加灵活,可以设置参数

推荐ThreadPoolTaskExecutor和ThreadPoolExecutor,而ThreadPoolTaskExecutor是ThreadPoolExecutor的封装,所以,性能更加优秀,推荐ThreadPoolTaskExecutor

4.这是ThreadPoolTaskExecutor用来初始化threadPoolExecutor的方法,BlockingQueue是一个阻塞队列,这个我们先不管。由于ThreadPoolTaskExecutor的实现方式完全是使用threadPoolExecutor进行实现,我们需要知道这个threadPoolExecutor的一些参数。

ThreadPoolExecutor的:

public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport implements SchedulingTaskExecutor {
    private final Object poolSizeMonitor = new Object();
    private int corePoolSize = 1;
    private int maxPoolSize = 2147483647;
    private int keepAliveSeconds = 60;
    private boolean allowCoreThreadTimeOut = false;
    private int queueCapacity = 2147483647;
    private ThreadPoolExecutor threadPoolExecutor;   //这里就用到了ThreadPoolExecutor

ThreadPoolTaskExecutor的:

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

参数说明:

    1、corePoolSize:核心线程数 (corePoolSize = cpu核心数 * 2 + 有效磁盘数)
 
    2、queueCapacity:任务队列容量(阻塞队列)
 
    3、maxPoolSize:最大线程数
       
    4、 keepAliveTime:线程空闲时间
 
    5、allowCoreThreadTimeout:允许核心线程超时 


    6、rejectedExecutionHandler:任务拒绝处理器
        * 两种情况会拒绝处理任务:
            - 当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务
            - 当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务
        * 线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常
        * ThreadPoolExecutor类有几个内部实现类来处理这类情况:
            - AbortPolicy 直接抛出java.util.concurrent.RejectedExecutionException异常
            - CallerRunsPolicy 若已达到待处理队列长度,将由主线程直接处理请求
            - DiscardPolicy 抛弃当前任务;会导致被丢弃的任务无法再次被执行
            - DiscardOldestPolicy 抛弃旧的任务;会导致被丢弃的任务无法再次被执行
        * 实现RejectedExecutionHandler接口,可自定义处理器

execute和submit的区别

提交任务类型

        execute和submitsubmitsubmit都属于线程池的方法,execute只能提交Runnable类型的任务

        submit既能提交Runnable类型任务也能提交Callable类型任务。

返回值

        execute()没有返回值

        submit有返回值,所以需要返回值的时候必须使用submit

        注意:submit的返回值为Future<?>,可通过get获取其泛型。Future<?>对象.get()方法具有阻塞当前线程的做用(也就是谁调用Future<?>对象.get()就阻塞谁,防止主线程在拿返回值时,而子线程还没有执行完)

线程池配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
public class ThreadPoolConfig {

    //获取cpu核心数
    private final static int AVAILABLE_PROCESSOR = Runtime.getRuntime().availableProcessors();

    /**
     * 通用线程池配置
     */
    @Bean("taskPoolExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //设置核心线程数
        taskExecutor.setCorePoolSize(6);
        //设置最大线程数
        taskExecutor.setMaxPoolSize(6*2);
        //设置队列最大容量
        taskExecutor.setQueueCapacity(12);
        //设置线程空闲时间(秒)
        taskExecutor.setKeepAliveSeconds(60);
        //设置线程名称前缀
        taskExecutor.setThreadNamePrefix("taskPoolExecutor--");
        //调度器shutdown方法被调用时等待当前被调度的任务完成
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        //等待时间(秒)
        taskExecutor.setAwaitTerminationSeconds(60);
        //拒绝策略
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        //初始化线程池
        taskExecutor.initialize();
        return taskExecutor;
    }

     /**
     * 发送短信线程池
     * @return
     */
    @Bean("sendSmsThreadPool")
    public Executor sendSmsThreadPool() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //设置线程池参数信息
        taskExecutor.setCorePoolSize(AVAILABLE_PROCESSOR);
        taskExecutor.setMaxPoolSize(AVAILABLE_PROCESSOR + 1);
        taskExecutor.setQueueCapacity(256);
        taskExecutor.setKeepAliveSeconds(20);
        taskExecutor.setThreadNamePrefix("sendSmsThreadPool--");
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        taskExecutor.setAwaitTerminationSeconds(60);
        //修改拒绝策略为使用当前线程执行
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //初始化线程池
        taskExecutor.initialize();
        return taskExecutor;
    }

    /**
     * 发送邮件线程池
     * @return
     */
    @Bean("sendEmailThreadPool")
    public Executor sendEmailThreadPool() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //设置线程池参数信息
        taskExecutor.setCorePoolSize(AVAILABLE_PROCESSOR);
        taskExecutor.setMaxPoolSize(AVAILABLE_PROCESSOR + 1);
        taskExecutor.setQueueCapacity(256);
        taskExecutor.setKeepAliveSeconds(20);
        taskExecutor.setThreadNamePrefix("sendEmailThreadPool--");
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        taskExecutor.setAwaitTerminationSeconds(60);
        //修改拒绝策略为使用当前线程执行
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //初始化线程池
        taskExecutor.initialize();
        return taskExecutor;
    }

    @Bean(name = "threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(5);
        executor.setQueueCapacity(10);
        executor.setKeepAliveSeconds(300);
        executor.setThreadNamePrefix("thread-ayokredit"); //线程名称
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }

    
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值