java REST 控制器是多线程的吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40794181/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is REST controller multithreaded?
提问by Humberd
I've been doing this tutorialabout how to return asynccallable object. It works as intended. Butwhile the first request sleeps for 5 seconds I get the second request, controller waitsfor the previous request to finnish before handling the second one.
我一直在做这个关于如何返回异步可调用对象的教程。它按预期工作。但是,当第一个请求休眠 5 秒时,我收到了第二个请求,控制器在处理第二个请求之前等待前一个请求完成。
How to make controller handle immediately every request and make sleeping in a background?
如何让控制器立即处理每个请求并在后台休眠?
@Edit
@编辑
Example: Imagine a situation, that my controller needs to make a request to external api and based on its response it should send his own response. External api call takes lets say 2 seconds. I want users of my application to wait only that 2,5 seconds and not be placed in queue, because the controller can handle only one request at a time.
示例:想象一种情况,我的控制器需要向外部 api 发出请求,并根据其响应发送自己的响应。外部 api 调用需要 2 秒。我希望我的应用程序的用户只等待 2.5 秒而不是被放入队列,因为控制器一次只能处理一个请求。
回答by developer
Is REST controller multithreaded?
REST 控制器是多线程的吗?
REST controller is multithreaded as the DisptcherServlet
handles multiple requests from the clients concurrently and serves using the respective controller methods. You can refer the request handling flow here
REST 控制器是多线程的,因为它同时DisptcherServlet
处理来自客户端的多个请求,并使用各自的控制器方法提供服务。您可以在此处参考请求处理流程
How to make controller handle immediately every request and make sleeping in a background?
如何让控制器立即处理每个请求并在后台休眠?
You can do that by returning Callable<String>
in the Spring controller method as shown below:
您可以通过Callable<String>
在 Spring 控制器方法中返回来实现,如下所示:
@Controller
public class MyController {
@RequestMapping(value="/sleep")
public Callable<String> myControllerMethod() {
Callable<String> asyncTask = () -> { try {
System.out.println(" WAITING STARTED:"+new Date());
Thread.sleep(5000);
System.out.println(" WAITING COMPLETED:"+new Date());
return "Return";//Send the result back to View Return.jsp
} catch(InterruptedException iexe) {
//log exception
return "ReturnFail";
}};
return asyncTask;
}
Output:
输出:
WAITING STARTED: Thu Nov 24 21:03:12 GMT 2016
等待开始:格林威治标准时间 2016 年 11 月 24 日星期四 21:03:12
WAITING COMPLETED: Thu Nov 24 21:03:17 GMT 2016
等待完成:格林威治标准时间 2016 年 11 月 24 日星期四 21:03:17
After this, the view will be returned "Return.jsp" page.
之后,视图将返回“Return.jsp”页面。
Here, the controller method will be running in a separate thread (releasing the actual servlet thread) and once the task is completed the Result will be sent back again to the client (View etc..).
在这里,控制器方法将在单独的线程中运行(释放实际的 servlet 线程),一旦任务完成,结果将再次发送回客户端(视图等)。
P.S.:You need to add @EnableAsync
as part of your application configuration, you can look hereon this.
PS:您需要添加@EnableAsync
作为应用程序配置的一部分,您可以查看这里。
回答by Fernando
What you want to do is what it is supposed to be done in the first example of the tutorial you linked:
您想要做的是在您链接的教程的第一个示例中应该完成的操作:
@RequestMapping(value = "/block", method = RequestMethod.GET, produces = "text/html")
public String executeSlowTask() {
logger.info("Request received");
Thread.sleep(5000);
logger.info("Servlet thread released");
return result;
}
This blocks the calling thread and waits till it is done. If you call from a different HTTP session, it will be another thread, so it will be a new 5 seconds wait (not affected by the first one).
这会阻塞调用线程并等待它完成。如果您从不同的 HTTP 会话调用,它将是另一个线程,因此将是一个新的 5 秒等待(不受第一个影响)。
Threads are linked to HTTP calls as long as there are threads available in the pool (configuration of the tomcat server).
只要池中有可用线程(tomcat 服务器的配置),线程就会链接到 HTTP 调用。
It is not the case that the controller will block all subsequent calls while busy. It is multithreaded.
控制器不会在繁忙时阻塞所有后续呼叫。它是多线程的。