1.配置线程池
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.*;
@Configuration
@EnableAsync
public class ThreadPoolTaskConfig {
private static final int corePoolSize = 10; // 核心线程数(默认线程数)
private static final int maxPoolSize = 100; // 最大线程数
private static final int keepAliveTime = 10; // 允许线程空闲时间(单位:默认为秒)
private static final int queueCapacity = 200; // 缓冲队列数
private static final String threadNamePrefix = "Async-Service-"; // 线程池名前缀
@Bean("taskExecutor")
public ThreadPoolTaskExecutor getAsyncExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveTime);
executor.setThreadNamePrefix(threadNamePrefix);
// 线程池对拒绝任务的处理策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 初始化
executor.initialize();
return executor;
}
}
2.定义service接口
import java.util.List;
import java.util.concurrent.ExecutionException;
public interface PullUserTaskService {
public void pullUser(List<Integer> userId) throws ExecutionException, InterruptedException, Exception;
public User getUserFormApi(Integer uid) throws Exception;
}
2.service实现类
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@Service
public class PullUserTaskServiceImpl implements PullUserTaskService {
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
@Autowired
private PullUserTaskService pullUserTaskService;
/**
* 根据用户的id进行拉取数据
* @param listUserId
*/
@Override
public void pullUser(List<Integer> listUserId) throws Exception {
List<Future<User> > listUser=new ArrayList<Future<User> >();
for (Integer uid : listUserId) {
Future<User> submit = taskExecutor.submit(new PullUserCallable(pullUserTaskService,uid));
listUser.add(submit);
}
//遍历返回值,如果线程没有执行完get方法将会阻塞等待线程执行完毕
for (Future<User> userFuture : listUser) {
//userFuture.get();
}
}
@Override
public User getUserFormApi(Integer uid) throws Exception{
//模拟http耗时5秒
TimeUnit.SECONDS.sleep(5);
//模拟httpClient请求获取新对象
System.out.println(Thread.currentThread().getName()+"线程发送http请求,参数:uid="+uid);
User user = new User();
user.setId(uid);
user.setName("张三"+new Random().nextInt(1000)+"号");
user.setColor(new Random().nextInt(1000)+"");
System.out.println(Thread.currentThread().getName()+"线程获取到api返回值"+user);
//调用dao方法完成保存操作
return user;
}
}
4.callable实现类
import java.util.concurrent.Callable;
public class PullUserCallable implements Callable<User> {
private Integer uid;
private PullUserTaskService pullUserTaskService;
public PullUserCallable(PullUserTaskService pullUserTaskService, Integer uid){
this.pullUserTaskService=pullUserTaskService;
this.uid=uid;
}
@Override
public User call() throws Exception {
long start=System.currentTimeMillis();
User userFormApi = pullUserTaskService.getUserFormApi(uid);
long end =System.currentTimeMillis()-start;
System.out.println(Thread.currentThread().getName()+"线程结束耗时:"+end);
return userFormApi;
}
}
5.测试
ArrayList<Integer> listUId = new ArrayList<>();
for (int i = 1; i <=num ; i++) {
listUId.add(i);
}
try {
pullUserTaskService.pullUser(listUId);
} catch (Exception e) {
e.printStackTrace();
}
6.多线程运行结果
Async-Service-3线程发送http请求,参数:uid=4
Async-Service-5线程发送http请求,参数:uid=1
Async-Service-2线程发送http请求,参数:uid=5
Async-Service-3线程获取到api返回值User{id=4, name='张三433号', color='699'}
Async-Service-1线程发送http请求,参数:uid=2
Async-Service-4线程发送http请求,参数:uid=3
Async-Service-4线程获取到api返回值User{id=3, name='张三151号', color='761'}
Async-Service-1线程获取到api返回值User{id=2, name='张三934号', color='635'}
Async-Service-3线程结束耗时:5005
Async-Service-5线程获取到api返回值User{id=1, name='张三240号', color='754'}
Async-Service-5线程结束耗时:5005
Async-Service-2线程获取到api返回值User{id=5, name='张三797号', color='368'}
Async-Service-1线程结束耗时:5005
Async-Service-4线程结束耗时:5005
Async-Service-2线程结束耗时:5005