Filter的線程安全問(wèn)題
Filter的線程安全問(wèn)題:
馬克- to-win:馬克 java社區(qū):防盜版實(shí)名手機(jī)尾號(hào): 73203。
馬克-to-win:和Servlet一樣,為了提高性能,F(xiàn)ilter也采取多線程模式。即:每一個(gè)線程來(lái)應(yīng)答一個(gè)用戶瀏覽器,而且這個(gè)線程和用戶要訪問(wèn)的目標(biāo)Servlet的線程是同一個(gè)線程。說(shuō)得更準(zhǔn)確一點(diǎn),當(dāng)用戶訪問(wèn)某個(gè)資源需要經(jīng)過(guò)過(guò)濾器時(shí),服務(wù)器中一個(gè)線程為了應(yīng)答這個(gè)客戶請(qǐng)求,先調(diào)用過(guò)濾器中的doFilter方法,再根據(jù)是否有chain.doFilter的指令,決定是否調(diào)用目標(biāo)資源的doXXX方法,當(dāng)然肯定還由這同一個(gè)線程調(diào)用。馬克 -to-win:執(zhí)行完doXXX方法以后,自然要繼續(xù)完成doFilter方法里面chain.doFilter語(yǔ)句后面的語(yǔ)句,這就和基本的C語(yǔ)言里主程序調(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í)驗(yàn):
設(shè)備:這個(gè)實(shí)驗(yàn)我是用三個(gè)瀏覽器一起做的:一個(gè)是火狐瀏覽器,一個(gè)是360瀏覽器,另外一個(gè)是eclipse自帶的內(nèi)置瀏覽器。
方法:訪問(wèn)的順序是,火狐一次,360一次,內(nèi)置瀏覽器一次,火狐最后一次。
實(shí)驗(yàn)輸出結(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
實(shí)驗(yàn)結(jié)論,當(dāng)用一個(gè)瀏覽器訪問(wèn)時(shí),系統(tǒng)會(huì)用同一個(gè)線程來(lái)運(yùn)行filter和servlet。但線程和瀏覽器沒(méi)有對(duì)應(yīng)關(guān)系。所以Filter的類變量和 servlet類變量一樣,都有線程安全問(wèn)題。有關(guān)線程安全問(wèn)題和解決方案請(qǐng)參考Servlet的線程安全。(我的前面jsp第二章)