2012-01-30 60 views
6

下面的程序:服務器創建的實例何時死亡?

public class SimpleCounter extends HttpServlet { 

    int counter=0; 

    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     response.setContentType("text/plain"); 
     PrintWriter writer = response.getWriter(); 
     counter++; 
     writer.println("accessed " + counter + " times"); 
    } 
} 

打印計數器的我每次訪問這個servlet的URL時間增加後的值。我讀過服務器創建這個servlet的一個實例,並且每當有這個servlet的請求時,一個新的線程將這個請求映射到服務器創建的特殊實例。

什麼時候由服務器創建的實例(線程映射請求)死?新請求創建的線程何時死亡?

+1

這是相對於特定的容器?有些人,比如Google App Engine,會積極回收一段時間內未收到請求的應用。 – 2012-01-30 17:21:27

+0

@麥克塞繆爾實際上不是。但可以包含在接聽/討論 – 2012-01-30 17:25:21

+0

相關:http://stackoverflow.com/questions/3106452/how-do-servlets-work-instantiation-session-variables-and-multithreading – BalusC 2012-01-30 18:27:42

回答

4

當你的web應用啓動時,或者首先需要它(如果懶初始化設置)創建的servlet實例。當你的web應用程序停止時,它被GCed處理掉。在一個正常的生產環境中,我敢說這永遠不會發生(不包括部署新版本)。

大部分(如果不是全部)servlet容器使用線程池工作。這意味着他們重用線程來處理請求。所以這些線程永不死亡;他們在完成執行請求時返回池。

當然,他們也死了,當你關閉服務器:)

從從應用程序的角度來看,你真的應該儘量讓你的servlet無狀態的,您可以放心地考慮每個請求的執行它自己的專用線程。

+0

_「你真的應該儘量使你的servlet無狀態「_你能解釋一下嗎? – 2012-01-30 16:44:05

+0

這意味着您不應該在那裏保留任何應用程序狀態。這樣你就不必在意它何時被創建或銷燬。理想情況下,你甚至不應該關心有多少實例化(這在集羣環境中很有用)。 – 2012-01-30 16:49:26

+0

@SuhailGupta,簡單地說,不要在Servlet中使用任何靜態變量。 – kosa 2012-01-30 16:50:50