SpringBoot使用异步线程池使程序无法关闭

又是一个困扰我在整整一天的难题,到了快23点,终于结束了,虽然很想睡觉,但还是得把它记录下来.                                               

今天在一个springBoot程序中想使用多线程(我的程序不是web),网上的教程有很多,大多都是使用

ThreadPoolTaskExecutor配合spring的异步注释@EnableAsync和@Async,具体的实现很简单,

网上的教程大抵上都差不多,如果想要了解,可以看这个SpringBoot对多线程的支持详解.这个例子很简单,

当我使用其中的多线程的配置完成后,关于线程池的执行任务方面完全没有问题,但是这个时候出现一个问题,

你也可以自己运行上面的教程中的例子,你会发现当线程池执行完任务后,整个SpringBoot被阻塞了,

没有关闭,就卡在线程池的任务执行完那里,就我后面解决后的理解来看,是线程池没有关闭,具体的原因我并不知道,

但是我猜测是因为SpringBoot对这个线程池的支持是异步的,一般异步线程是需要Future配合通知关闭的,

然后我就开始搜索答案,百度显然不管用,国内的帖子的解决办法只有一个,就是在线程池的创建的地方加上

setWaitForTasksToCompleteOnShutdown(true),
setAwaitTerminationSeconds(60);

大致的意思看名字就可以以看的出来,就是等60秒后关闭,但是这个并没有什么乱用,然后我就遁入stackoverflow,

这里的解决方案就很多了,我试了几种,再结合自己的理解,找到了一种方法,就是在最后运行的主类中

加入一个之前配置的ThreadPoolTaskExecutor的Bean,显性的运行完线程后执行shutdown(),

有一点需要注意的是,上面的例子中的执行内容很简单,可能主线程在其他任务没有执行完成前就获得了执行的权限,

导致任务没有执行完,就关闭了线程池,这里就需要一个Java并发工具CountDownLatch,

大家可以自行了解使用,我觉得和join没什么区别,但是需要在线程池中使用,好了问题就这样了

猜你喜欢

转载自blog.csdn.net/qq_36865108/article/details/82919434