2016-12-31 47 views
0

我不知道它的安全(死鎖沒有概率)使用靜態方法內部的J2EE Web過濾器或我應該使用實例方法? 我有以下doFilter方法在J2EE WebFilter過濾器中使用靜態方法是否安全?

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
    HttpServletRequest httpServletRequest = (HttpServletRequest) request; 
    HttpServletResponse httpServletResponse = (HttpServletResponse) response; 
    String contextPath = httpServletRequest.getContextPath(); 
    if ((httpServletRequest.getRequestedSessionId() != null && 
      !httpServletRequest.isRequestedSessionIdValid()) || (loginBean == null || loginBean.getUserId() == -1)) { 
     httpServletResponse.sendRedirect(contextPath + Navigation.getLoginURL()); 


    } else { 
     chain.doFilter(request, response); 
    } 
} 

Navigation.getLoginURL()

是一個靜態方法。這可能導致僵局嗎?

+0

死鎖當一個線程被阻塞,在等待另一個線程鎖定的資源,反之亦然發生。這裏沒有任何鎖定。那麼爲什麼會出現僵局呢?如果多個請求嘗試同時點擊過濾器,則返回 –

+0

。 – Jim

+0

然後呢?他們都會同時執行你的靜態方法。 –

回答

1

這是一個靜態方法的關鍵是有一個在過濾器實例的狀態沒有依賴關係;登錄網址在應用程序中是相同的。由於沒有保護的狀態,所以沒有理由鎖定任何東西。

具有一個靜態方法來一些東西,鎖(像的System.out.println)的調用並不意味着你的代碼將出現死鎖。實現api servlet和過濾器的Java EE代碼應該避免進行大量的鎖定,因爲它需要支持高水平的併發性。

望着這但從實施者的角度應該幫助你決定,你可以安全地調用了什麼,看到Java併發的這句話在實踐中,部分4.5.1(模糊的解釋文件):

你是將不得不猜測。提高猜測質量的一種方法是從實施它的人(如容器或數據庫供應商)的角度解釋規範,而不是僅僅使用它的人。 Servlet總是從容器管理的線程中調用,並且假設如果有多個這樣的線程,容器知道這一點是安全的。 servlet容器提供了爲多個servlet提供服務的某些對象,如HttpSession或ServletContext。所以servlet容器應該期望同時訪問這些對象,因爲它已經創建了多個線程並從中調用了像Servlet.service這樣的方法,這些方法可以合理地期望訪問ServletContext。

因爲它是不可能想象一個單線程的上下文中,這些對象將是有用的,人們認爲他們已經作出線程安全的,即使該規範並沒有明確要求這一點。此外,如果他們需要客戶端鎖定,客戶端代碼應該同步什麼鎖?文件沒有說,猜測似乎很荒唐。這個「合理的假設」進一步得到了規範和官方教程中的例子的支持,這些例子展示瞭如何訪問ServletContext或HttpSession,並且不使用任何客戶端同步。