2012-03-12 76 views
4

我知道,對於servlet的每個請求,執行doPost()或doGet()方法,init()方法中的代碼wirtten只被初始化一次。但是,在所有這些方法之外編寫的代碼呢?
該代碼是否也被線程化了?我指的是在那部分聲明的變量,如果它們在doPost()中被修改,這些變化是否會反映到servlet的其他請求中?在servlet的init()方法外部聲明的變量

回答

5

在普通的servlet容器中,只有一個servlet對象的實例。這個對象可以被任何數量的線程使用 - 每個請求一個線程。管理servlet實例的生命週期取決於servlet容器。

因此,在任何方法(包括init())中更改類變量的值時,它將影響所有後續請求。 更改或聲明方法中的局部變量當然不會影響任何內容,因爲下次調用該方法時,會再次創建局部變量(並在方法結束時被垃圾收集器銷燬)。

1

Servlet的實例由容器合併。所以任何數量的Servlet對象都可以被真實世界場景中的任意數量的線程共享。所有的doXXX()方法和從它們調用的其他方法都將由線程共享。

因此,非常不鼓勵在Servlet中有類級變量(用於維護狀態)。雖然你可以肯定有常量,靜態幫助器方法和靜態變量,它們也被實例共享,而不是由使用Servlet的客戶端不斷修改。

雖然不鼓勵,但沒有阻止你使變量/方法同步。這將確保一次只有一個線程訪問資源,但是會有性能損失,因爲線程在佔用鎖之前可能必須等待其他人先釋放資源。

但還有一個更好的方法,如果您希望用Servlet維護狀態並希望爲每個客戶端存儲變量,則您的Servlet應實現javax.servlet.SingleThreadModel。如果你的Servlet實現了這個標記接口,容器就會知道它維持狀態,因此每個實例只能提供一個線程。

+0

javax.servlet.SingleThreadModel已棄用。 – 2012-03-13 04:24:00