2012-04-26 56 views
5

當請求到達處理文件上傳的servlet時,在該servlet中使用new Thread(r).start()啓動一個新線程是一個好主意,該線程將處理文件附帶的另一條數據上傳。我希望能夠同時處理這兩項工作。在servlet中啓動一個新線程

+0

我會勸阻它,除非你使用線程池。另外,Servlet 3現在有異步服務調用,爲什麼不探討? – 2012-04-26 08:53:56

+0

你正在使用哪個應用服務器?它是否爲長時間運行的任務提供某種支持? – BigMike 2012-04-26 08:58:18

+0

@BigMike Glassfish 3.1.1 – saplingPro 2012-04-26 08:59:27

回答

17

這不僅是一個壞主意,但它也行不通。這是爲什麼:您的文件上傳請求最終會碰到doPost()方法。只要你在這個方法中,容器就保持連接打開。一旦您從該方法返回(並且如果您決定在單獨的線程中處理傳入數據,則doPost()將盡早完成),容器假定您已完成請求並關閉連接。從客戶端角度來看,上傳被服務器中斷。由於線程的異步特性,中斷將在隨機時刻發生。

相信我,一些用戶已經體驗到了這一點:HttpServletResponse seems to periodically send prematurely

此外,對於每個請求啓動新線程是一個壞主意,因爲這個比例很差(甚至某些規範禁止它)。 可以做的是使用Servlet 3.0異步請求並處理異步上傳,但最好使用一些線程池。另見:Why create new thread with startAsync instead of doing work in servlet thread?

+0

......糟糕的主意,除非你需要做一些長時間運行的CPU密集型任務。 – 2012-04-26 09:02:58

+0

@Tomasz Nurkiewicz即使我將新線程的工作放在該servlet的doPost()方法內? – saplingPro 2012-04-26 09:06:18

+0

@Tomasz Nurkiewicz從這個servlet的post方法內部的線程的run方法中派發一個新的請求到另一個servlet會好嗎? – 2012-04-26 09:11:59

-5

在Servlet中啓動新線程沒有什麼錯(與EJB不同),所以是的,沒關係。

編輯:第二個想法@Tomasz Nurkiewicz是正確的。文件上傳將被停止。

+0

不正確的是,需要管理在併發環境中編寫線程。 – 2012-04-26 08:55:06

+0

只要線程沒有使用任何非本地變量(servlet中的字段)就沒有問題。我假設一切都發生在doGet/doPost方法中 – 2012-04-26 08:58:26

-2

Servlets通過web服務器隱式在新線程中運行,所以無論何時任何請求遇到一個servlet,它都將在不同的線程中執行。我沒有預見到自己創建新線程的原因

+0

也許只是爲了不讓客戶端凍結(如果線程很耗時?) – BigMike 2012-04-26 08:56:50

+0

所以用戶不必等待servlet完成上傳 – 2012-04-26 08:57:32

+0

http://www.adam- bien.com/roller/abien/entry/are_servlets_thread_safe_and – 2012-04-26 08:57:33