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

Servlet 同步優化:避免主代碼路徑加鎖,採用細粒度鎖對象

     編輯:Java 相關知識

核心原則

Servlet 本質多線程,主代碼路徑(service/doGet/doPost)嚴禁同步,否則退化為單線程,吞吐量劇降。若不可避免需保護共享狀態,請使用 專用鎖對象 並 將同步塊縮小至最小必要範圍。

反面教材:過度同步

public class BadServlet extends HttpServlet {
    private int numberOfRows = 0;
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        synchronized (this) { // 鎖住整個 Servlet 實例!
            int startingRows = numberOfRows;
            // 資料庫操作、業務邏輯... 全在鎖內
        }
    }
}

後果:併發請求排隊,CPU 閒置,響應時間隨並發線性增長。

最佳實踐:細粒度鎖

public class GoodServlet extends HttpServlet {
    private int numberOfRows = 0;
    private final Object lockObject = new Object(); // 專用鎖
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        int startingRows;
        synchronized (lockObject) { // 僅保護讀取共享變量
            startingRows = numberOfRows;
        }
        // 資料庫操作、耗時邏輯在鎖外並發執行
        Connection conn = ds.getConnection(...);
        // ...
    }
}

性能對比圖解

同步性能影響對比圖

圖示:同步主路徑(紅線)隨並發用戶數響應時間指數級上升;細粒度鎖(藍線)近似線性增長。

其他避坑指南

  • 避免實現 SingleThreadModel:已棄用,容器會建立多實例,資源浪費且線程安全假象。
  • 優先使用無狀態設計:Servlet 實例變量改為方法局部變量、ThreadLocal 或請求屬性。
  • 共享資源用併發集合:ConcurrentHashMap、AtomicInteger 等無鎖結構。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved