2014-03-05 21 views
2

從servlet啓動線程的推薦方式是什麼?我們如何從一個servlet開始一個線程?

示例:一位用戶向遊戲房間發佈新聊天消息。我想向所有連接到房間的其他玩家發送推送通知,但它不必同步發生。就像:

public MyChatServlet extends HttpServlet { 

    protected void doPost(HttpServletRequest request, 
          HttpServletResponse response) 
    { 
     // Update the database with the new chat message. 
     final String msg = ...; 
     putMsgInDatabaseForGameroom(msg); 

     // Now spawn a thread which will deal with communicating 
     // with apple's apns service, this can be done async. 
     new Thread() { 
      public void run() { 
       talkToApple(msg); 
       someOtherUnimportantStuff(msg); 
      } 
     }.start(); 

     // We can send a reply back to the caller now. 
     // ... 
    } 
} 

我使用Jetty,但我不知道在這種情況下Web容器真的很重要。

謝謝

回答

0

我會使用ThreadPoolExecutor並將任務提交給它。執行器可以配置固定/不同數量的線程,並且可以配置一個工作隊列,可以是有界限的或不可界定的。

優點:

  • 線程總數(以及隊列的大小),可以有界的,所以你必須對資源消耗良好的控制。
  • 的線程池,消除線程的開銷每個請求
  • 開始,你可以選擇一個任務拒絕策略(發生在池是滿負荷)
  • 您可以輕鬆地監控池的負荷
  • 遺囑執行人機制支持跟蹤異步操作的便捷的方式(使用Future
+0

好吧,你會做一個包裝ThreadPoolExecutor實例的單例,並且所有的servlet實例都將它們的任務轉儲到那裏? – user3203425

+0

@ user3203425:是的,這對我來說似乎很合理。您可能希望有多個執行者用於不同的目的,因此其中一個執行者的負載不會影響另一個執行者。仔細調整池和隊列大小,以使它們符合您的預期流量速率和可接受的任務延遲。 –

+0

好吧,我沒有在我的項目中使用servlet 3.0,我決定使用threadpoolexecutor,它似乎運行良好。 – user3203425

0

一般來說就是這樣。您可以在servlet Web應用程序中的任何位置啓動任何線程。

但特別是,您應該保護您的JVM免於在任何HTTP請求上啓動太多的線程。有人可能會要求很多(或者非常非常多),並且在某些時候你的JVM會因爲內存不足或類似的情況而停下來。

所以更好的選擇是使用java.util.concurrent軟件包中的一個隊列。

0

一種選擇是使用ExecutorService及其實現像ThreadPoolExecutor 來重新使用池化線程,從而減少創建開銷。

您也可以使用JMS來爲稍後執行的任務排隊。

1

什麼是從一個servlet啓動一個線程的推薦的方法?

在servlet中編寫線程程序時應該非常小心。 因爲它可能導致錯誤(如內存泄漏或缺少同步)可能會導致很難重現的錯誤,或者導致整個服務器崩潰。

您可以使用start()方法啓動線程。

據我所知,我會推薦startAsync(servlet 3.0)。 我收到了一些對你有用的鏈接Click

但我不知道在這種情況下web容器是否真的很重要。

是的,它很重要。大多數web服務器(Java和其他,包括JBoss)遵循「每個請求一個線程」模型,即每個HTTP請求完全由一個線程處理。 此線程通常會花費大部分時間等待數據庫請求等事情。 Web容器將根據需要創建新線程。

希望它能幫助你。

+0

好吧,聽起來很有希望,但我需要更新到一個servlet 3.0容器。 – user3203425

相關問題