pom.xml配置导入如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
yml文件添加多线程核心配置
server:
#端口号
port: 8080
spring:
task:
pool:
corePoolSize: 4
maxPoolSize: 8
keepAliveSeconds: 60
queueCapacity: 20
corePoolSize不宜超过cpu核心数
创建线程池参数装载类:
@ConfigurationProperties(prefix = “spring.task.pool”)是让spring在创建bean时去加载配置文件中开头为spring.task.pool的内容,如果的配置文件位置不同的话可以引用别处。
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "spring.task.pool")
public class TaskThreadPoolConfig {
private int corePoolSize;
private int maxPoolSize;
private int keepAliveSeconds;
private int queueCapacity;
public int getCorePoolSize() {
return corePoolSize;
}
public void setCorePoolSize(int corePoolSize) {
this.corePoolSize = corePoolSize;
}
public int getMaxPoolSize() {
return maxPoolSize;
}
public void setMaxPoolSize(int maxPoolSize) {
this.maxPoolSize = maxPoolSize;
}
public int getKeepAliveSeconds() {
return keepAliveSeconds;
}
public void setKeepAliveSeconds(int keepAliveSeconds) {
this.keepAliveSeconds = keepAliveSeconds;
}
public int getQueueCapacity() {
return queueCapacity;
}
public void setQueueCapacity(int queueCapacity) {
this.queueCapacity = queueCapacity;
}
}
spring boot 启动类上加上注解:
@EnableConfigurationProperties({TaskThreadPoolConfig.class})
这个不能忘记,不然没法异步
@Configuration
@SpringBootApplication(scanBasePackages = "com",exclude = DataSourceAutoConfiguration.class)
@MapperScan(basePackages = "com.aistar.resources.mapper")
@EnableConfigurationProperties({TaskThreadPoolConfig.class})
public class LoginServiceApplication {
public static void main(String[] args) {
SpringApplication.run(LoginServiceApplication.class, args);
}
}
下面是一个简单demo使用方法:
测试类代码如下:
@SpringBootTest
class LoginServiceApplicationTests {
@Autowired
SysLoginUserService sysLoginUserService;
@Autowired
AsyncService asyncService;
@Autowired
SysParameterMapper sysParameterMapper;
@Value("${config.jwt.secret}")
private String secret;
@Test
void contextLoads() {
}
@Test
public void test() throws ExecutionException, InterruptedException{
long start = System.currentTimeMillis();
Map<String, Object> map = new HashMap<>();
List<Future<String>> futures = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Future<String> future = asyncService.doReturn(i);
futures.add(future);
}
List<String> response = new ArrayList<>();
for (Future future : futures) {
String string = (String) future.get();
response.add(string);
}
map.put("data", response);
map.put("消耗时间", String.format("任务执行成功,耗时{%s}毫秒", System.currentTimeMillis() - start));
System.out.println(map);
}
}
创建service层:
public interface AsyncService {
Future<String> doReturn(int i);
void doReturnNores(int i);
}
实现类:
@Service
public class AsyncServiceImpl implements AsyncService {
@Async("taskAsyncPool")
public Future<String> doReturn(int i){
try {
// 这个方法需要调用500毫秒
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 消息汇总
return new AsyncResult<>(String.format("这个是第{%s}个异步调用的证书", i));
}
@Async("taskAsyncPool")
public void doReturnNores(int i){
try {
// 这个方法需要调用500毫秒
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
执行结果:
- {data=[这个是第{0}个异步调用的证书, 这个是第{1}个异步调用的证书, 这个是第{2}个异步调用的证书,
这个是第{3}个异步调用的证书, 这个是第{4}个异步调用的证书, 这个是第{5}个异步调用的证书, 这个是第{6}个异步调用的证书,
这个是第{7}个异步调用的证书, 这个是第{8}个异步调用的证书, 这个是第{9}个异步调用的证书, 这个是第{10}个异步调用的证书,
这个是第{11}个异步调用的证书, 这个是第{12}个异步调用的证书, 这个是第{13}个异步调用的证书,
这个是第{14}个异步调用的证书, 这个是第{15}个异步调用的证书, 这个是第{16}个异步调用的证书,
这个是第{17}个异步调用的证书, 这个是第{18}个异步调用的证书, 这个是第{19}个异步调用的证书,
这个是第{20}个异步调用的证书, 这个是第{21}个异步调用的证书, 这个是第{22}个异步调用的证书,
这个是第{23}个异步调用的证书, 这个是第{24}个异步调用的证书, 这个是第{25}个异步调用的证书,
这个是第{26}个异步调用的证书, 这个是第{27}个异步调用的证书, 这个是第{28}个异步调用的证书,
这个是第{29}个异步调用的证书, 这个是第{30}个异步调用的证书, 这个是第{31}个异步调用的证书,
这个是第{32}个异步调用的证书, 这个是第{33}个异步调用的证书, 这个是第{34}个异步调用的证书,
这个是第{35}个异步调用的证书, 这个是第{36}个异步调用的证书, 这个是第{37}个异步调用的证书,
这个是第{38}个异步调用的证书, 这个是第{39}个异步调用的证书, 这个是第{40}个异步调用的证书,
这个是第{41}个异步调用的证书, 这个是第{42}个异步调用的证书, 这个是第{43}个异步调用的证书,
这个是第{44}个异步调用的证书, 这个是第{45}个异步调用的证书, 这个是第{46}个异步调用的证书,
这个是第{47}个异步调用的证书, 这个是第{48}个异步调用的证书, 这个是第{49}个异步调用的证书,
这个是第{50}个异步调用的证书, 这个是第{51}个异步调用的证书, 这个是第{52}个异步调用的证书,
这个是第{53}个异步调用的证书, 这个是第{54}个异步调用的证书, 这个是第{55}个异步调用的证书,
这个是第{56}个异步调用的证书, 这个是第{57}个异步调用的证书, 这个是第{58}个异步调用的证书,
这个是第{59}个异步调用的证书, 这个是第{60}个异步调用的证书, 这个是第{61}个异步调用的证书,
这个是第{62}个异步调用的证书, 这个是第{63}个异步调用的证书, 这个是第{64}个异步调用的证书,
这个是第{65}个异步调用的证书, 这个是第{66}个异步调用的证书, 这个是第{67}个异步调用的证书,
这个是第{68}个异步调用的证书, 这个是第{69}个异步调用的证书, 这个是第{70}个异步调用的证书,
这个是第{71}个异步调用的证书, 这个是第{72}个异步调用的证书, 这个是第{73}个异步调用的证书,
这个是第{74}个异步调用的证书, 这个是第{75}个异步调用的证书, 这个是第{76}个异步调用的证书,
这个是第{77}个异步调用的证书, 这个是第{78}个异步调用的证书, 这个是第{79}个异步调用的证书,
这个是第{80}个异步调用的证书, 这个是第{81}个异步调用的证书, 这个是第{82}个异步调用的证书,
这个是第{83}个异步调用的证书, 这个是第{84}个异步调用的证书, 这个是第{85}个异步调用的证书,
这个是第{86}个异步调用的证书, 这个是第{87}个异步调用的证书, 这个是第{88}个异步调用的证书,
这个是第{89}个异步调用的证书, 这个是第{90}个异步调用的证书, 这个是第{91}个异步调用的证书,
这个是第{92}个异步调用的证书, 这个是第{93}个异步调用的证书, 这个是第{94}个异步调用的证书,
这个是第{95}个异步调用的证书, 这个是第{96}个异步调用的证书, 这个是第{97}个异步调用的证书,
这个是第{98}个异步调用的证书, 这个是第{99}个异步调用的证书], 消耗时间=任务执行成功,耗时{6014}毫秒}
每个线程500ms,100次执行结果下耗时6014,还算是ok的节约不少时间,我觉得还有优化空间。
如果是不需要返回结果的话可以执行下方这段test2,比如短信发送这类业务。
一般如果是并行查询数据的话应该都是要返回数据的,需要返回数据需要用Future<> 包裹,取得时候也是要先get出来,否则是没法阻塞的。
@Test
public void test2() throws ExecutionException, InterruptedException{
long start = System.currentTimeMillis();
Map<String, Object> map = new HashMap<>();
List<Future<String>> futures = new ArrayList<>();
for (int i = 0; i < 100; i++) {
asyncService.doReturnNores(i);
}
}
以上就是全部教程了,学习犹如逆水行舟,不进则退。
参考文章:https://blog.csdn.net/u012480379/article/details/82899926