我想知道它是否安全(没有死锁的可能性)在J2ee web过滤器中使用静态方法,或者我应该使用实例方法? 我有以下doFilter方法
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 :(得分:1)
这是静态方法的要点是不依赖于Filter实例的状态;整个应用程序的登录URL是相同的。由于没有保护状态,没有理由锁定任何东西。
在静态方法中调用一些锁定的东西(如System.out.println)并不意味着你的代码会死锁。实现api servlet和过滤器的Java EE代码应避免执行大量锁定,因为它需要支持高级别的并发性。
从实施者的角度来看这应该可以帮助您确定可以安全地调用的内容,请参阅Java Concurrency in Practice,第4.5.1节(解释模糊文档)中的引用:
你将不得不猜测。提高猜测质量的一种方法是从实施它的人(例如容器或数据库供应商)的角度解释规范,而不是仅仅使用它的人。 Servlet总是从容器管理的线程调用,可以安全地假设如果有多个这样的线程,容器就知道这一点。 servlet容器使某些对象可以为多个servlet提供服务,例如HttpSession或ServletContext。因此,servlet容器应该期望同时访问这些对象,因为它已经创建了多个线程并从中调用了Servlet.service等方法,这些方法可以合理地期望访问ServletContext。
由于无法想象这些对象有用的单线程上下文,因此必须假设它们已经成为线程安全的,即使规范没有明确要求这样做。此外,如果他们需要客户端锁定,客户端代码应该在什么锁上同步?文档没有说,猜测似乎很荒谬。规范和官方教程中的示例进一步证明了这种“合理的假设”,它们展示了如何访问ServletContext或HttpSession,并且不使用任何客户端同步。