我知道,對於servlet的每個請求,執行doPost()或doGet()方法,init()方法中的代碼wirtten只被初始化一次。但是,在所有這些方法之外編寫的代碼呢?
該代碼是否也被線程化了?我指的是在那部分聲明的變量,如果它們在doPost()
中被修改,這些變化是否會反映到servlet的其他請求中?在servlet的init()方法外部聲明的變量
4
A
回答
5
在普通的servlet容器中,只有一個servlet對象的實例。這個對象可以被任何數量的線程使用 - 每個請求一個線程。管理servlet實例的生命週期取決於servlet容器。
因此,在任何方法(包括init())中更改類變量的值時,它將影響所有後續請求。 更改或聲明方法中的局部變量當然不會影響任何內容,因爲下次調用該方法時,會再次創建局部變量(並在方法結束時被垃圾收集器銷燬)。
3
由defaut Servlets不是線程安全的。一個servlet實例將被許多客戶端調用。將狀態存儲在servlet內部作爲實例變量是絕對錯誤的。
參考文獻:
1
Servlet的實例由容器合併。所以任何數量的Servlet對象都可以被真實世界場景中的任意數量的線程共享。所有的doXXX()方法和從它們調用的其他方法都將由線程共享。
因此,非常不鼓勵在Servlet中有類級變量(用於維護狀態)。雖然你可以肯定有常量,靜態幫助器方法和靜態變量,它們也被實例共享,而不是由使用Servlet的客戶端不斷修改。
雖然不鼓勵,但沒有阻止你使變量/方法同步。這將確保一次只有一個線程訪問資源,但是會有性能損失,因爲線程在佔用鎖之前可能必須等待其他人先釋放資源。
但還有一個更好的方法,如果您希望用Servlet維護狀態並希望爲每個客戶端存儲變量,則您的Servlet應實現javax.servlet.SingleThreadModel
。如果你的Servlet實現了這個標記接口,容器就會知道它維持狀態,因此每個實例只能提供一個線程。
相關問題
- 1. 在外部聲明變量
- 2. 如何在方法外部使用在方法中聲明的變量?
- 3. 我應該在重用方法的外部還是內部聲明變量?
- 4. 在java中聲明變量的方法
- 5. 無法訪問在開關語句外部聲明的變量
- 6. c#方法聲明變量
- 7. C++方法變量聲明
- 8. Ruby方法變量聲明
- 9. 爪哇 - 外部變量聲明
- 10. JavaScript變量聲明的不同方法
- 11. 聲明類方法中的新變量
- 12. 聲明變量的不同方法?
- 13. Javascript中的變量聲明方法
- 14. 在方法參數中聲明變量
- 15. 區分聲明變量與未聲明的方法
- 16. 方法 - 本地內部類不能使用在方法中聲明的變量
- 17. 局部變量在聲明內部循環時無法解析,但在外部聲明時不能解析NPE
- 18. 在servlet的doget()方法中調用init()
- 19. 最好在循環內部或外部聲明臨時變量?
- 20. 在servlet外部訪問會話變量
- 21. 無法聲明全局變量外部函數
- 22. 在局部變量聲明語句中,在塊聲明中,聲明語句的哪個部分是聲明符?
- 23. 在PHP類中聲明受保護的變量,使用外部變量
- 24. 訪問變量到方法聲明中
- 25. VBScript執行方法不聲明變量
- 26. 使用BEM方法聲明Sass變量
- 27. 在APPLICATION中聲明所有常量變量的最佳方法
- 28. 在foreach循環之外聲明變量
- 29. 在函數之外聲明變量
- 30. 在onCreate之外聲明變量 - Android
javax.servlet.SingleThreadModel已棄用。 – 2012-03-13 04:24:00