ThreadPoolExecutor和ThreadPoolTaskExecutor的区别
-
ThreadPoolExecutor,这个类是JDK中的线程池类,继承自Executor,里面有一个execute()方法,用来执行线程,线程池主要提供一个线程队列,队列中保存着所有等待状态的线程,避免了创建与销毁的额外开销。
-
ThreadPoolTaskExecutor,是spring包下的,是Spring为我们提供的线程池类。Spring异步线程池的接口类是TaskExecutor,本质还是java.util.concurrent.Executor
ThreadPoolTaskExecutor的使用方式:
-
spring会先搜索TaskExecutor类型的bean或者名字为taskExecutor的Executor类型的bean
-
自定义一个线程池,加入Spring IOC容器里面,即可覆盖
配置:
package cn.company.config;
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.ThreadPoolExecutor;
/**
* 描述:自定义线程池
* 在配置类中加@EnableAsync那就不需要在启动类再次重复写了
*
* @Author:
*/
@Configuration
@EnableAsync
public class ThreadPoolTaskConfig {
@Bean("threadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//线程池创建的核心线程数,线程池维护线程的最少数量,即使没有任务需要执行,也会一直存活
//如果设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭直到关闭为0
executor.setCorePoolSize(8);
// 缓存队列(阻塞队列)当核心线程数达到最大时,新任务会放在队列中排队等待执行。
// 需注意,如果设置的过大可能造成服务的oom
executor.setQueueCapacity(1024);
// 最大线程池数量,当线程数>=corePoolSize,且阻塞队列已满时。线程池会创建新线程来处理任务
// 有任务进来时:优先使用核心线程池(CorePoolSize)>>然后进入阻塞队列(QueueCapacity)>>然后开启新的线程(maxPoolSize)>>进入拒绝策略
executor.setMaxPoolSize(64);
//当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize
//允许线程空闲时间30秒,当maxPoolSize的线程在空闲时间到达的时候销毁
executor.setKeepAliveSeconds(30);
// spring 提供的 ThreadPoolTaskExecutor 线程池,是有setThreadNamePrefix() 方法的。
// jdk 提供的ThreadPoolExecutor 线程池是没有 setThreadNamePrefix() 方法的
executor.setThreadNamePrefix("customize_async_task");
// 优雅退出,在程序关闭时是否等待计划任务完成
executor.setWaitForTasksToCompleteOnShutdown(true);
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CallerRunsPolicy():交由调用方线程运行,比如 main 线程;如果添加到线程池失败,那么主线程会自己去执行该任务,不会等待线程池中的线程去执行
// AbortPolicy():该策略是线程池的默认策略,如果线程池队列满了丢掉这个任务并且抛出RejectedExecutionException异常。
// DiscardPolicy():如果线程池队列满了,会直接丢掉这个任务并且不会有任何异常
// DiscardOldestPolicy():丢弃队列中最老的任务,队列满了,会将最早进入队列的任务删掉腾出空间,再尝试加入队列
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
executor.initialize();
return executor;
}
}
调用方使用:
package cn.company.service.push;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
/**
* 描述:
*
* @Author:
*/
@Service
@Slf4j
public class WeChatAsyncServiceImpl implements WeChatAsyncService {
@Autowired
private RestTemplate restTemplate;
@Override
@Async("threadPoolTaskExecutor")
public void sendMessageTemplate(JSONObject message, String token) {
log.info("自己的业务逻辑");
}
}