Java SpringMVC:如果我在控制器动作中启动一个线程,会发生什么?

Java SpringMVC:如果我在控制器动作中启动一个线程,会发生什么?,java,spring,multithreading,spring-mvc,Java,Spring,Multithreading,Spring Mvc,在SpringMVC控制器中,我希望启动一个线程,在控制器发送响应时继续工作。这对SpringMVC有效吗 最好的收获, 海因里希是的,它会起作用的。在我开发的一个web应用程序上,我需要根据用户的操作发送通知电子邮件。我在服务中添加了一个post-commit拦截器,并让它在一个单独的线程中触发电子邮件。(在我的例子中,这恰好比将代码放入控制器更干净,因为我只希望在事务提交时发生。) 您确实需要通过将daemon设置为true(如果停止服务器可以在没有通知的情况下终止线程)或确保run方法中的

在SpringMVC控制器中,我希望启动一个线程,在控制器发送响应时继续工作。这对SpringMVC有效吗

最好的收获,
海因里希是的,它会起作用的。在我开发的一个web应用程序上,我需要根据用户的操作发送通知电子邮件。我在服务中添加了一个post-commit拦截器,并让它在一个单独的线程中触发电子邮件。(在我的例子中,这恰好比将代码放入控制器更干净,因为我只希望在事务提交时发生。)

您确实需要通过将daemon设置为true(如果停止服务器可以在没有通知的情况下终止线程)或确保run方法中的代码始终在某个点终止,来确保线程在某个点实际停止运行


使用线程池比创建新线程更好,这样就不会有资源耗尽的风险(线程暂停通常不是独立事件,如果一个线程挂起,下一个线程也可能挂起,因此需要一种减少损失的方法)。带有@Async注释的方法将使用一个执行器执行,您可以配置该执行器,如中所示。

是的,您可以在控制器中启动新线程。但执行异步作业的更好方法是使用spring调度支持。您可以利用Quartz框架。那会管理好你的工作


这将告诉您如何将其集成到应用程序中

正如其他人所提到的,它将起作用<代码>执行器服务可以完成此工作。在这里,您可以看到我使用它来启动位于单独端点上的视频流

@PostMapping("/capture")
public ResponseEntity capture() {
    // some code omitted
    ExecutorService service = Executors.newCachedThreadPool();
    service.submit(() -> startStreaming(deviceConfig));
    return return ResponseEntity.ok()
            .body(stream);
}

也许值得一提的是,当发送电子邮件失败时,控制器无法通知用户(除非您使用Callable.get(),这会破坏另一个线程的用途)。如果我想使用线程池,如何实现服务器上的所有用户/请求都只使用一个线程池?编辑:这可以通过将threadpool bean的范围限定为“singleton”来实现吗?您可以稍微解释一下为什么在这种情况下使用spring scheduling/Quartz比启动一个新线程更好吗?