一、介绍
1、介绍
二、原理
三、集成与使用
1、集成方法
(1)开启
使用以下注解开启
@EnableAsync
(2)使用
在需要异步处理的方法上加上
@Async
2、返回值
@Async注解的方法返回值只能为void或者Future<T>。
(1)无返回值
(2)有返回值
使用AsyncResult包装下得到Future对象返回;调用处使用get方法获取。
3、demo
(1)初始化线程池
如我初始化了两个,分别在user模块、order模块使用
package com.demo.thread.constant;
public class ThreadPoolConstant {
public static final String USER_POOL = "userPool";
public static final String ORDER_POOL = "orderPool";
}
package com.demo.thread.config;
import com.demo.thread.constant.ThreadPoolConstant;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
@EnableAsync
public class ThreadPoolTaskExecutorConfig {
private static int CORE_POOL_SIZE = 5;
private static int MAX_POOL_SIZE = 10;
@Bean(name= ThreadPoolConstant.USER_POOL)
public ThreadPoolTaskExecutor userTaskExecutor(){
ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
//线程池维护线程的最少数量
poolTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);
//线程池维护线程的最大数量
poolTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
//线程池所使用的缓冲队列
poolTaskExecutor.setQueueCapacity(200);
//线程池维护线程所允许的空闲时间
poolTaskExecutor.setKeepAliveSeconds(30000);
poolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
poolTaskExecutor.setBeanName(ThreadPoolConstant.USER_POOL);
return poolTaskExecutor;
}
@Bean(name= ThreadPoolConstant.ORDER_POOL)
public ThreadPoolTaskExecutor orderTaskExecutor(){
ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
//线程池维护线程的最少数量
poolTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);
//线程池维护线程的最大数量
poolTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
//线程池所使用的缓冲队列
poolTaskExecutor.setQueueCapacity(200);
//线程池维护线程所允许的空闲时间
poolTaskExecutor.setKeepAliveSeconds(30000);
poolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
poolTaskExecutor.setBeanName(ThreadPoolConstant.ORDER_POOL);
return poolTaskExecutor;
}
}
(2)service
package com.demo.thread.service.impl;
import com.demo.thread.constant.ThreadPoolConstant;
import com.demo.thread.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;
@Service("userService")
@Slf4j
public class UserServiceImpl implements UserService {
@Override
@Async(ThreadPoolConstant.USER_POOL)
public void create() {
log.info("user create开始...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.info("user create结束...");
}
@Override
@Async(ThreadPoolConstant.USER_POOL)
public Future<List<String>> query() {
log.info("user query 开始...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
List<String> userIds = new ArrayList<>();
userIds.add("zs");
userIds.add("ls");
Future<List<String>> users = new AsyncResult(userIds);
log.info("user query 结束...");
return users;
}
}
(3)controller
package com.demo.thread.controller;
import com.demo.thread.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@RestController
@RequestMapping("/test")
@Slf4j
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/create")
public void create() {
log.info("测试create开始");
userService.create();
log.info("测试create结束");
}
@RequestMapping("/query")
public void query() {
log.info("测试query开始");
Future<List<String>> users = userService.query();
log.info("调用query结束");
try {
List<String> userIds = users.get();
log.info("query结果为:{}",userIds);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
log.info("测试query结束");
}
}
(4)启动类
package com.demo.thread;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ThreadApplicationStart {
public static void main(String[] args) {
SpringApplication.run(ThreadApplicationStart.class, args);
}
}
(5)测试
无返回值:访问localhost:8080/test/create控制台输出:
有返回值:访问localhost:8080/test/query控制台输出:可以看到feture取结果会阻塞主线程,其他则按执行顺序打印