前言
异步线程可能会非常小号cpu资源,大项目推荐使用mq异步实现。
1 App.java
@SpringBootApplication
@EnableAsync // 开启异步注解
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
2 Controller
/*
* @Author : 有勇气的牛排(全网同名)
* @FileName: CsAsync.java
* desc :
* */
package com.couragesteak.controller;
import com.couragesteak.service.MemberServiceAsync;
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;
@RestController
@Slf4j
public class CsAsync {
@Autowired
private MemberServiceAsync memberServiceAsync;
// http://127.0.0.1:8080/a_register
@RequestMapping("/a_register")
public String A_Register() {
log.info(">>> 01");
memberServiceAsync.smsAsync();
log.info(">>> 03");
return "注册成功";
}
}
3 service
/*
* @Author : 有勇气的牛排(全网同名)
* @FileName: MemberServiceAsync.java
* desc :
* */
package com.couragesteak.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class MemberServiceAsync {
@Async("taskExecutor") // 指定线程池
public String smsAsync() {
log.info(">>> 2");
try {
log.info("正在发送中");
Thread.sleep(3000);
} catch (Exception e) {
}
return "恭喜注册成功";
}
}
4 多线程池封装
/*
* @Author : 有勇气的牛排(全网同名)
* @FileName: ThreadPoolConfig.java
* desc : 线程池配置
* */
package com.couragesteak.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@EnableAsync
public class ThreadPoolConfig {
/**
* 每秒需要多少个线程处理?
* tasks/(1/taskcost)
*/
private int corePoolSize = 3;
/**
* 线程池维护线程的最大数量
* (max(tasks)- queueCapacity)/(1/taskcost)
*/
private int maxPoolSize = 3;
/**
* 缓存队列
* (coreSizePool/taskcost)*responsetime
*/
private int queueCapacity = 10;
/**
* 允许的空闲时间
* 默认为60
*/
private int keepAlive = 100;
@Bean
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置核心线程数
executor.setCorePoolSize(corePoolSize);
// 设置最大线程数
executor.setMaxPoolSize(maxPoolSize);
// 设置队列容量
executor.setQueueCapacity(queueCapacity);
// 设置允许的空闲时间(秒)
//executor.setKeepAliveSeconds(keepAlive);
// 设置默认线程名称
executor.setThreadNamePrefix("thread-");
// 设置拒绝策略rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
return executor;
}
}