簡體   English   中英

在Java中,如何確保我的Web應用程序是線程安全的?

[英]In Java, How do I make sure my web application is thread safe?

如何確保我的java servlet Web應用程序是線程安全的? 關於會話變量,類的靜態變量或其他任何可能是線程安全問題的問題,我需要做些什么?

事實:在webapp的生命周期中,只有一個servlet實例。 它在webapp的啟動時創建,並在webapp關閉時被銷毀。 另請參閱此答案以獲得粗略的解釋。

因此,它在所有請求(線程)之間共享。 如果您將請求或會話范圍數據分配為實例(或者更糟,更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.
    } 
}

這基本上是在開發具有線程安全性的servlet時需要考慮的全部內容。

然后是會話( HttpSession )屬性,可以在同一用戶的多個請求之間共享,但在現實世界中,您實際上不需要擔心同步會話訪問。 您通常只在那里放置用戶特定的數據,例如登錄用戶,用戶特定的偏好,購物籃等。 您只需確保不將純請求范圍數據放在會話范圍中。 它會反映在同一會話中的多個瀏覽器窗口/選項卡中。

然后是應用程序( ServletContext )屬性,這些屬性在應用程序范圍內的所有用戶之間共享,但是您通常只放置常量和其他靜態數據,例如webapp配置,DAO工廠,下拉列表內容等。 這一切都可以通過ServletContextListener完成,也可以看一下這個答案的基本示例。 您只需確保不將純請求或會話范圍的數據放在應用程序范圍中。

哇,這是一個有問題的問題。

簡而言之,您需要確保仔細同步對任何共享數據的訪問。 例如,您可能希望使用互斥鎖或同步函數同步對靜態變量的訪問。

請注意,如果您需要同時修改多個共享資源的原子事務,則可能還需要在更高級別進行同步。

設計並發應用程序並不簡單,並且沒有靈丹妙葯(不幸的是)。 我強烈推薦“ Java Concurrency in Practice ”一書,以獲取有關編寫安全並發代碼的更多信息。

你的意思是在上下文中,而不是任何其他Java應用程序? 確實沒有太大區別。 對servlet的每個請求都會導致容器發出一個新線程來處理它,因此servlet中的實例變量必須是線程安全的。 最好在doGet / doPost()方法中使用局部變量處理所有業務。 有一個我能想到的問題。 對於會話變量,可能會出現用戶打開兩個瀏覽器窗口的情況,這兩個窗口都指向您的應用程序。 在這種情況下,您還需要注意會話范圍的線程安全性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM