2017-03-23 149 views
0

下面是從新澤西州docs樣本代碼異步服務:JAXRS異步服務

@Path("/resource") 
public class AsyncResource { 
    @GET 
    public void asyncGet(@Suspended final AsyncResponse asyncResponse) { 

     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       String result = veryExpensiveOperation(); 
       asyncResponse.resume(result); 
      } 

      private String veryExpensiveOperation() { 
       // ... very expensive operation 
      } 
     }).start(); 
    } 
} 

考慮到容器已經負責釋放連接處理線程返回池中,並交給請求處理的工作線程,我想知道爲什麼我們仍然需要以編程方式產生一個新的線程?這不應該只是容器配置(設置工作線程數)的問題嗎?

回答

1

有沒有必要spwan這樣的新線程。如果你是在JavaEE的環境中,你可以簡單地將一個@Asynchronous註解你的方法:

@GET 
@Asynchronous 
public void asyncGet(@Suspended final AsyncResponse asyncResponse) { 
     String result = veryExpensiveOperation(); 
     asyncResponse.resume(result); 
} 

我需要擴展線程池您還可以看看ManagedExecutorService

+0

它不那麼簡單。首先,資源必須標記爲EJB。第二:你需要一個完整的配置文件服務器,因爲web配置文件不支持@Asynchronous –

+0

是的,我忘記提及'AsyncResource'需要成爲一個EJB。您也可以將異步方法放到單獨的EJB中。 – simdevmon

0

不應該只是容器配置(設置工作線程數)的問題嗎?

其實你可以配置容器工作線程的數量,但是你仍然受它們的束縛。如果你有10個容器線程,那麼你可以同時處理10個請求。如果您有100個線程,則可以有100個併發請求

另一方面,異步Web請求將工作線程中的請求/響應對象(以及在servlet-container部署的情況下,jax-rs使用下面的servlet) 。因此你可以有10個線程,但是有1000個請求(保持閱讀)。

我想知道爲什麼我們仍然需要以編程方式產生一個新的線程?

如果您仍然要在同一個線程中處理它,那麼將請求與線程分離是沒有意義的,因爲在這種情況下,異步/同步請求之間完全沒有區別。

你也不需要產生一個新的線程。其實這是一個可怕的解決方案。創建線程很昂貴。相反,您應該將可運行內容提交給線程池。

那麼異步請求有什麼好處呢?它們適合需要花費大量時間才能完成的操作。做下面的實驗。

  1. 配置tomcat(或您選擇的服務器)使用10個線程池。
  2. 讓您的資源只休眠10秒鐘。
  3. 儘可能多地請求它。
  4. 使您的資源處於異步狀態,而不是等待它,將僅等待10秒的runnables提交到線程池 - >現在可以創建多少個請求?