1首先配置线程池
package com.liyajie.config;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@EnableAsync // 启用异步任务
public class ThreadConfig implements AsyncConfigurer {
//定义线程池
@Bean("musicThreadPool")
public Executor getMusicThreadPool() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
//核心线程数
taskExecutor.setCorePoolSize(8);
//最大线程数
taskExecutor.setMaxPoolSize(20);
//缓冲队列
taskExecutor.setQueueCapacity(300);
//允许空闲时间,空闲超过指定时间后被销毁
taskExecutor.setKeepAliveSeconds(60);
//设置线程池的前缀名
taskExecutor.setThreadNamePrefix("music-thread-pool");
//缓冲队列满了之后的拒绝策略,由调用线程处理
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
taskExecutor.initialize();
return taskExecutor;
}
}
Bean名字可以不用。
2创建异步方法
@SneakyThrows
public void updateMusicSimilarity(){
List<SongSimilarity> list = getUpdateMusicSimilarity();
int size = list.size();
for (int i=0;i<list.size()/1000+1;i++){
List<SongSimilarity> collect = list.stream()
.skip(i * 1000)
.limit(1000)
.collect(Collectors.toList());
asyncService.updateMusicSimilarityByAsync(collect);
}
}
@Async
@SneakyThrows
public void updateMusicSimilarityByAsync(List<SongSimilarity> list){
recommendationSongMapper.insertAll(list);
log.info(Thread.currentThread().getName());
log.info("插入成功");
Thread.sleep(2000);
}
3调用
@GetMapping("/updateMusicSimilarity")
public void updateMusicSimilarity(){
recommendationSongService.updateMusicSimilarity();
}
4出错
在日志中可以看到,此时是单线程运行的,原因是因为:不能在同一个类中去调用另一个异步方法。比如,A类中有方法b,c,c为异步方法,在b中调用c不会启用启用异步,我们可以将c方法放在B类中。
解决
创建异步方法类B
package com.liyajie.service;
import com.liyajie.entity.SongSimilarity;
import com.liyajie.mapper.RecommendationSongMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@Slf4j
public class AsyncService {
@Autowired
private RecommendationSongMapper recommendationSongMapper;
@Async("musicThreadPool")
@SneakyThrows
public void updateMusicSimilarityByAsync(List<SongSimilarity> list){
recommendationSongMapper.insertAll(list);
log.info(Thread.currentThread().getName());
log.info("插入成功");
Thread.sleep(2000);
}
}
此时调用则会异步执行。
问题解决