springboot与线程池搭配使用(两个注解:@EnableAsync与@Async)
三步走:
1:配置线程池
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
* 线程池配置
*
* @author route
**/
@EnableAsync // 主意第一个注解出现
@Configuration
public class ThreadPoolConfig {
// 核心线程池大小
private int corePoolSize = 50;
// 最大可创建的线程数
private int maxPoolSize = 200;
// 队列最大长度
private int queueCapacity = 1000;
// 线程池维护线程所允许的空闲时间
private int keepAliveSeconds = 300;
@Bean(name = "threadPoolTaskExecutor") // 这里是给线程池取的名字,配置不同的线程池取不一样的名字
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize); // 核心线程池大小
executor.setMaxPoolSize(maxPoolSize); // 最大可创建的线程数
executor.setQueueCapacity(queueCapacity); // 队列最大长度
executor.setKeepAliveSeconds(keepAliveSeconds);// 线程池维护线程所允许的空闲时间
executor.setThreadNamePrefix("tsak-record-userData"); //线程前缀名称
// 线程池对拒绝任务(无线程可用)的处理策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 交给调用线程处理.(这里有多种拒绝策略可以自定义)
return executor;
}
}
2:自定义线程任务
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* 线程任务
*/
@Component
public class Task {
@Async("threadPoolTaskExecutor") // 主意第二个注解出现,括号的内容就代表你用的是哪个线程池
public void testThread(int i) {
long start = System.currentTimeMillis();
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("丛线程:第"+i+"完成任务.耗时:"+(end-start)+"毫秒.线成名为:"+Thread.currentThread().getName());
}
}
3:主线程调用
@Controller
public class RecordController {
@Autowired
private Task task; // 注入线程对象
@GetMapping("index")
public String index() {
System.out.println("主线程任务准备起飞");
for (int i = 0; i <= 5; i++) {
task.testThread(i);
}
System.out.println("主线程走完:" + Thread.currentThread().getName());
return null;
}
}
查看输出
主线程任务准备起飞
主线程走完:http-nio-80-exec-1
丛线程:第4完成任务.耗时:1000毫秒.线成名为:tsak-record-userData5
丛线程:第0完成任务.耗时:1000毫秒.线成名为:tsak-record-userData1
丛线程:第1完成任务.耗时:1000毫秒.线成名为:tsak-record-userData2
丛线程:第3完成任务.耗时:1000毫秒.线成名为:tsak-record-userData4
丛线程:第5完成任务.耗时:1000毫秒.线成名为:tsak-record-userData6
丛线程:第2完成任务.耗时:1000毫秒.线成名为:tsak-record-userData3
虽然学完不会让你了解其底层原理,蛋似至少会用了吧.