2016-11-24 59 views
1

我一直在做这个tutorial关于如何返回异步可调用对象。它按预期工作。 而第一个请求睡5秒我得到第二个请求,控制器等待为先前的请求芬兰语之前处理第二个。REST控制器是多线程的吗?

如何使控制器立即处理每个请求,并在后台进行睡眠?

@Edit

例子: 想象的情况,我的控制器需要向外部API的请求,并根据其响应应该发送自己的响应。外部API调用需要说2秒。我希望我的应用程序的用户只等2.5秒,而不是放在队列中,因为控制器一次只能处理一个请求。

+0

它不是已经回答了吗? http://stackoverflow.com/questions/35196157/spring-non-blocking-rest-send-and-forget –

回答

4

REST控制器是多线程的吗?

REST控制器是多线程的,因为DisptcherServlet同时处理来自客户端的多个请求,并使用各自的控制器方法提供服务。您可以参考请求处理流程here

如何使控制器手柄马上每一个请求,并 在后台睡觉?

你可以做到这一点,如下图所示在Spring控制器方法返回Callable<String>

@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; 
    } 

输出:

WAITING已启动:星期四11月24日21时03分12秒格林尼治标准时间2016

等候完成:Thu Nov 24 21:03:17 GMT 2016

之后,视图将返回“Return.jsp”页面。

在这里,控制器方法将运行在一个单独的线程中(释放实际的servlet线程),一旦任务完成,结果将被发送回客户端(视图等)。

P.S:您需要添加@EnableAsync为您的应用程序配置的一部分,你可以看看这个here

+0

我想返回一个响应后,5秒,而不是立即 – Humberd

+0

我已经更新了我的答案,我得到了你的要求 – developer

+0

我已经尝试过,但是当我使用POSTMAN发送请求时,响应正好在(11ms)之后。它不会等所有 – Humberd

0

你想要做的是什么是应该在你的链接教程的第一个例子做:

@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; 
} 

这阻塞调用线程,并等待,直到它完成。如果你从另一个HTTP会话中调用,它将是另一个线程,所以它将是一个新的5秒等待(不受第一个影响)。

只要池中有可用线程(tomcat服务器的配置),线程就会链接到HTTP调用。

控制器不会在忙时阻止所有后续呼叫。它是多线程的。

+0

对我来说,它阻止了每个输入请求 – Humberd

+0

然后你有某种配置问题。你是在虚拟机器还是其他类型的受限制的环境中? – Fernando

+0

不,我在我的私人计算机上拥有所有管理权限 – Humberd