在日常的开发工作中,我们经常会需要使用到线程池这类型的组件。例如下边几种应用场景:
线程池经典应用场景
异步发送邮件通知
发送一个任务,然后注入到线程池中异步发送。
心跳请求任务
创建一个任务,然后定时发送请求到线程池中。
类似的场景有很多,我们下边一步一步地来介绍不同的应用场景下,线程池的具体使用案例:
异步发送邮件场景
实体类
@Data
public class EmnailBo {
private String receiver;
private String title;
private String content;
}
:
Controller
@Api(tags = "Email")
@RestController // @Controller+@ResponseBody{将数据以Json 形式返回}
@RequestMapping("/thread")
public class EmailDemo {
@Autowired
private ThreadPoolExecutor emailTaskPool;
@GetMapping("/SendEmail")
public Result SendEmail (){
EmnailBo emnailBo = new EmnailBo();
emnailBo.setContent("fuhg");
emnailBo.setTitle("iudfhg");
sendEmail(emnailBo);
return Result.ok();
}
// 发送 邮件
public void sendEmail(EmnailBo emailDTO) {
emailTaskPool.submit(()-> {
try {
System.out.println("fg");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
);
}
我们创建了一个 MailSender 类,它实现了 Runnable 接口,并且重写了 run() 方法。在 run() 方法中,我们首先输出发送邮件的地址,然后通过 Thread.sleep() 方法来模拟发送邮件的耗时操作。最后输出邮件发送成功的信息。
在 main() 方法中,我们创建了一个 MailSender 对象,然后将其传递给一个新的线程,并通过 start() 方法启动线程。接着输出主线程继续运行的信息。
当程序运行时,邮件发送逻辑将在单独的线程中执行,并且主线程将继续运行,直到邮件发送逻辑完成。这种方式可以避免阻塞主线程,提高程序的响应性能和并发性能。
自定义线程池
@Configuration
public class ThreadPool {
@Bean
public ThreadPoolExecutor threadPoolExecutor(){
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
5, // io-2n cpu-n+1
10,
3,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
return threadPoolExecutor;
};
}