Executors new CachedThreadPool():可缓存线程池
Executors new FixedTheadPool():可定长度
Executors new ScheduledThreadPool():可定时
Executors new SingleTheadExecutor():单例
但在springboot当中一般使用spring自带的
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
ThreadPoolExecutor是Java原生的线程池类,而ThreadPoolTaskExecutor是Spring推出的线程池工具
ThreadPoolTaskExecutor 和 ThreadPoolExecutor 的区别
ThreadPoolTaskExecutor和ThreadPoolExecutor有何区别
ThreadPoolTaskExecutor和ThreadPoolExecutor区别
线程池构造函数里面的参数
corePoolSize:核心线程数即一直运行的线程数
maximumPoolSize:最大线程数
keepAliveTime:超出corePoolSize后创建线程的存活时间
unit:KeepAliveTime的时间单位
workQueue:任务队列,用于保存待执行的任务
threadFactory:线程池内部创建线程所用的工厂
handler:任务无法执行时的处理器
拒绝策略
AbortPolicy:丢弃任务,抛运行时异常
CallerRunsPolicy:执行任务
DiscardPolicy:忽视,什么都不会发生
DiscardOldestPolicy:从队列中踢出最先进入队列(最后一个执行)的任务。
实现RejectedExecutionHandler接口,可自定义处理器。
在springboot中使用线程池十分简单,可参考
比如你需要异步导入excel
只需要先在启动类加个@EnableAsync开启异步线程池
在写个配置类
@Configuration
@EnableAsync
public class ExeConfig {
private static final Logger logger = LoggerFactory.getLogger(ExeConfig.class);
@Bean
public Executor asyncServiceExecutor() {
logger.info("start asyncServiceExecutor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(10);
//配置最大线程数
executor.setMaxPoolSize(30);
//配置队列大小
executor.setQueueCapacity(99999);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix("excle-async-service-");
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}
在写个实现类就行
方法1
@Slf4j
@Service
public class AsyncExportService {
@Async("asyncServiceExecutor")
public void exportXXX() {
//业务代码
}
然后注入使调用
@Autowired
private AsyncExportService asyncExportService;
...
...
AsyncExportService.exportXXX();
...
当然也可以把异步方法直接写在原本类似这种,就不用另外启用异步类来写异步方法了@Async(“asyncServiceExecutor”)注解了,但是还是推荐写法1,将异步方法放一起。
方法2
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
...
...
threadPoolTaskExecutor.execute(() ->this.incr(tagId,TAG_CLICK_VOLUME));
...
public void incr(Long id,String key) {
Map<String, Object> map = redisService.getCacheMap(key);
Integer value = (Integer) map.get(id.toString());
// 如果key存在就直接加一
if (value != null) {
map.put(id.toString(),value+1);
}else {
map.put(id.toString(),1);
}
redisService.setCacheMap(key,map);
}
调用A接口返回a耗时1分钟,调用B接口返回b耗时1分钟,怎么使得a+b在1分钟左右
IO密集型和计算密集型(CPU密集型)具体的区分
线程池的大小如何确定
单核与多核
相关连接