首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Servlet 生命週期與線程安全實戰

     編輯:Java 相關知識

Servlet 生命週期三階段

  1. 初始化: 容器實例化 Servlet,調用 init(ServletConfig),僅執行一次。
  2. 服務: 每個請求分配一線程調用 service(req, res),默認分發到 doGet/doPost 等方法。
  3. 銷毀: 容器卸載時調用 destroy() 釋放資源,隨後由 GC 回收。

實例持久化與線程安全隱患

Servlet 默認單例模式:一個 Servlet 類對應一個實例服務所有請求。實例變量(如計數器 count)成為共享可變狀態,併發訪問導致競態條件。

錯誤示例

public class SimpleCounter extends HttpServlet {
    int count = 0; // 共享變量
    public void doGet(HttpServletRequest req, HttpServletResponse res) {
        count++; // 非原子操作:讀-改-寫
        out.println("Accessed " + count + " times");
    }
}

修正方案

  • 同步塊: synchronized(this) { count++; ... } 粒度較大,影響並發度。
  • ThreadLocal: 請求級隔離,不共享。
  • 原子類: AtomicInteger count = new AtomicInteger(); count.incrementAndGet(); 無鎖高效。
  • 無狀態設計: 業務數據放請求域/會話域/數據庫,Servlet 僅作調度器,不持有可變狀態(推薦)。

Servlet 重載與熱部署

開發期容器監測類文件變更自動重載 Servlet,生產環境需關閉以提升性能。重載會銷毀舊實例、創建新實例,init 再次執行,需妥善處理資源釋放與重新獲取。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved