如何確保我的java servlets web應用程序是線程安全的?關於會話變量,類的靜態變量或其他任何可能成爲線程安全問題的事情,我需要做些什麼?在Java中,如何確保我的Web應用程序是線程安全的?
回答
事實:這裏只有1中的servlet實例在Web應用程序的一生。它在webapp的啓動時創建,並在webapp關閉時被破壞。另請參閱this answer進行粗略解讀。
因此,它已在所有請求(線程)之間共享。如果將請求或會話作用域數據作爲實例(或更糟糕的話,作爲static
)變量,那麼它絕對不是線程安全的,因爲它在應用程序範圍內的所有用戶(會話)的所有請求(線程)之間共享。您只需將它們分配爲方法局部變量,以使它們保持線程安全。所以:
public class MyServlet extends HttpServlet {
private Object thisIsNOTThreadSafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadSafe;
thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
}
}
這基本上是您在開發考慮thread安全性的servlet時需要考慮的全部內容。
然後會話(HttpSession
)屬性可以在同一用戶的多個請求之間共享,但在現實世界中,您實際上並不需要擔心同步會話訪問。您通常只將用戶特定的數據放在那裏,例如登錄用戶,用戶特定偏好,購物籃等等。您只需確保不要將純請求範圍數據放入會話範圍中。它會反映在同一個會話中的多個瀏覽器窗口/選項卡中。
然後,應用程序(ServletContext
)屬性在所有用戶的應用程序範圍內共享,但通常只在其中放置常量和其他靜態數據,如web應用程序配置,DAO工廠,dropdownlist內容等。這一切都可以通過ServletContextListener
完成,也可以參考this answer的基本示例。您只需確保不要將純請求或會話範圍的數據放入應用程序範圍中。
您的意思是在上下文中而不是其他任何Java應用程序?真的沒有太大的區別。每個對servlet的請求都會導致容器發出一個新線程來處理它,因此servlet中的實例變量必須是線程安全的。最好在doGet/doPost()方法中使用局部變量處理所有商業。有一個我能想到的問題。使用會話變量時,可能會出現這樣的情況:用戶有兩個打開的瀏覽器窗口,都指向您的應用程序。在這種情況下,您需要注意線程安全性以及會話範圍。
哇,這是一個加載的問題。
簡而言之,您需要確保對任何共享數據的訪問仔細同步。例如,您可能想要使用互斥鎖或同步函數來同步對靜態變量的訪問。
請注意,如果您需要同時修改多個共享資源的原子事務,則可能還需要在較高級別進行同步。
設計一個併發應用程序並不簡單,也沒有神奇的項目符號(不幸的是)。我強烈推薦編寫「Java Concurrency in Practice」這本書,以獲取更多關於編寫安全併發代碼的信息。
- 不使用servlet的實例變量和過濾器
- 不使用靜態變量
- read this article on session thread safety
- 認爲
- 1. 在線安全的web應用程序
- 2. iOS的Web應用程序 - 我如何確保我的應用程序登錄是安全
- 3. Java - 如何從GUI中安全地停止Web應用程序中的線程?
- 4. 線程安全應用程序中的線程安全
- 5. Java Web應用程序中的線程
- 6. Web應用程序中的線程Java
- 7. 在Java Web應用程序中使用Ehcache是否安全?
- 8. Java Web應用程序安全理念
- 9. web應用程序中的線程安全
- 10. 確保代碼中的線程安全
- 11. 保持我的Java程序安全
- 12. Web應用程序與OpenAM的安全性如何保護
- 13. Web應用程序安全
- 14. Web應用程序安全
- 15. tomcat中的安全web應用程序
- 16. J2EE7中的Web應用程序安全
- 17. 確保我的代碼是線程安全的
- 18. 如何確保移動應用程序的安全性
- 19. 我的應用程序是否安全?
- 20. 如何確保共享變量是線程安全的?
- 21. 如何確保PostgreSQL驅動器是線程安全的
- 22. 如何在C++應用程序中編譯sqlite3線程安全?
- 23. java線程安全:線程安全嗎?
- 24. 如何確定應用程序是否是Web應用程序
- 25. 單線程應用程序是否線程安全
- 26. java web應用程序中的不安全對象引用
- 27. 從反彙編程序保護我的應用程序安全
- 28. Web應用程序的登錄安全
- 29. ASP.NET Web應用程序的安全庫
- 30. 如何分析Java源代碼並確保它是線程安全的
有關「在Web應用程序的一生中使用一個servlet」的一個問題 - 我認爲這是一個池對象,所以根據負載的不同,servlet引擎可能會有不止一個。這不正確嗎? – duffymo 2010-02-10 21:56:15
只有它實現(按照Servlet 2.4棄用)'SingleThreadModel'。 – BalusC 2010-02-10 22:18:03
@BalusC:非常感謝您,先生,這個答案最終幫了我。我刪除了我的問題,並提出了你的答案。 Java中沒有人喜歡你。再次感謝一百萬。 – 2016-06-06 14:30:28