2016-11-24 81 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