Filter的線程安全問題
Filter的線程安全問題:
馬克- to-win:馬克 java社區(qū):防盜版實名手機尾號: 73203。
馬克-to-win:和Servlet一樣,為了提高性能,F(xiàn)ilter也采取多線程模式。即:每一個線程來應(yīng)答一個用戶瀏覽器,而且這個線程和用戶要訪問的目標Servlet的線程是同一個線程。說得更準確一點,當用戶訪問某個資源需要經(jīng)過過濾器時,服務(wù)器中一個線程為了應(yīng)答這個客戶請求,先調(diào)用過濾器中的doFilter方法,再根據(jù)是否有chain.doFilter的指令,決定是否調(diào)用目標資源的doXXX方法,當然肯定還由這同一個線程調(diào)用。馬克 -to-win:執(zhí)行完doXXX方法以后,自然要繼續(xù)完成doFilter方法里面chain.doFilter語句后面的語句,這就和基本的C語言里主程序調(diào)用子程序的規(guī)則一樣了。
例 1.2.6
package com;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletHello1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
System.out.println(Thread.currentThread().getName()+"hello");
}
}
package com;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;
public class MarkToWinFilter implements Filter {
public MarkToWinFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
response.setCharacterEncoding("GBK");
System.out.println(Thread.currentThread().getName()+"之前 filterChain.doFilter");
chain.doFilter(request, response);
System.out.println(Thread.currentThread().getName()+"之后 filterChain.doFilter");
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
實驗:
設(shè)備:這個實驗我是用三個瀏覽器一起做的:一個是火狐瀏覽器,一個是360瀏覽器,另外一個是eclipse自帶的內(nèi)置瀏覽器。
方法:訪問的順序是,火狐一次,360一次,內(nèi)置瀏覽器一次,火狐最后一次。
實驗輸出結(jié)果:
http-8080-Processor25之前 filterChain.doFilter
http-8080-Processor25hello
http-8080-Processor25之后 filterChain.doFilter
http-8080-Processor22之前 filterChain.doFilter
http-8080-Processor22hello
http-8080-Processor22之后 filterChain.doFilter
http-8080-Processor23之前 filterChain.doFilter
http-8080-Processor23hello
http-8080-Processor23之后 filterChain.doFilter
http-8080-Processor24之前 filterChain.doFilter
http-8080-Processor24hello
http-8080-Processor24之后 filterChain.doFilter
實驗結(jié)論,當用一個瀏覽器訪問時,系統(tǒng)會用同一個線程來運行filter和servlet。但線程和瀏覽器沒有對應(yīng)關(guān)系。所以Filter的類變量和 servlet類變量一樣,都有線程安全問題。有關(guān)線程安全問題和解決方案請參考Servlet的線程安全。(我的前面jsp第二章)