程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 避免或最小化Servlet中的同步

避免或最小化Servlet中的同步

編輯:關於JAVA

摘要

最小化 servlet 中同步的使用。因為 servlet 是多線程的,主要代碼路徑的同步會嚴重地且極為有害地影響性能。

建議

servlet 是多線程的。基於 servlet 的應用程序必須認識並適當地處理這一點。如果應用程序有很多大段的代碼是同步的,那麼這個應用程序實際上就變成單線程的,而且吞吐量會顯著下降。

在 servlet 中不出現同步是最佳選擇,然而,如果應用程序設計無法避免同步,那麼請使用“鎖對象(lock Object)”並且鎖定可用性最小的代碼路徑。請不要同步 servlet 的 service 方法或 doGet 以及 doPost 方法。這些方法是主要代碼路徑。同步這些方法或任何這些 servlet 方法之一將鎖定整個 servlet 實例。下列代碼顯示了一個使用“鎖對象”來保護 servlet 實例變量 numberOfRows 的示例。

最小同步代碼路徑

public class BpAllBadThingsServletsV1b extends HttpServlet
{
  private int numberOfRows = 0;
  private javax.sql.DataSource ds = null;
  private Object lockObject = new Object();
  public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
   {
        Connection conn = null;
        ResultSet rs = null;
        PreparedStatement pStmt = null;
        int startingRows = 0;
        synchronize(lockObject)        {
                 startingRows = numberOfRows;
        }
        try
        {
             String employeeInformation = null;
             conn = ds.getConnection("db2admin", "db2admin");
             pStmt = conn.prepareStatement
               ("select * from db2admin.employee");
             rs = pStmt.executeQuery();
        }
        catch (Exception es)
        {
            // Error handling code here
        }
   }
}

應被取代的方法

以下代碼顯示如何同步主要代碼路徑來保護稱為 numberOfRows 的 servlet 實例變量。

使用 javax.servlet.SingleThreadModel 仍是另一種保護 servlet 實例變量的方法,但最好還是避免使用這種方法。

下面的圖 1 顯示了同步的性能影響

鎖定主要代碼路徑:過度的同步

    public class BpAllBadThingsServletsV1a extends HttpServlet
{
   private int numberOfRows = 0;
   private javax.sql.DataSource ds = null;
   public void doGet(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException
   {
       Connection conn = null;
       ResultSet rs = null;
       PreparedStatement pStmt = null;
       int startingRows;
       try
       {
         synchronized(this) // Locks out Most of the Servlet Processing
         {
             startingRows = numberOfRows;
             String employeeInformation = null;
             conn = ds.getConnection("db2admin", "db2admin");
             pStmt = conn.prepareStatement
               ("select * from db2admin.employee");
             rs = pStmt.executeQuery();
         }
       }
       catch (Exception es)
       {
         // Error handling code here
       }
   }
}

圖 1 -- 性能影響 -- 同步

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved