1. 程式人生 > >[J2EE] Servlet執行緒不安全的體現以及解決方式 筆記

[J2EE] Servlet執行緒不安全的體現以及解決方式 筆記

        對於例項變數來說,由於servlet在Tomcat中是以單例模式存在的,所有的執行緒共享例項變數。多個執行緒對共享資源的訪問造成了執行緒不安全問題。

案例如下:

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * @author zWX240091
 *
 */
public class HelloWorldServlet extends HttpServlet
{
    String message;
    /**
     * 
     */
    private static final long serialVersionUID = 787553024399133588L;
    public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
        message =request.getParameter("message");
        PrintWriter pw = response.getWriter();
        try
        {
            Thread.sleep(5000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        pw.write("<div><strong>Hello World</strong>!</div>"+message);
        pw.close();
    }
    
}

在構建好的工程部署到本地Tomcat下,啟動Tomcat,開啟倆個瀏覽器

訪問1: http://localhost:8080/Servlet03/HelloWorld?message=helloA

訪問2: http://localhost:8080/Servlet03/HelloWorld?message=helloB

分別重新整理訪問,在訪問第一個地址的頁面打印出了helloB,在訪問第二個地址的時候頁面有時候會打印出helloA。這個就是高併發下的多執行緒的安全問題。

解決方式:

  1. 新增同步程式碼鎖 synchronized
  2. 將要訪問的例項變數改為區域性變數多執行緒下每個執行緒對區域性變數都會有自己的一份copy,這樣對區域性變數的修改只會影響到自己的copy而不會對別的執行緒產生影響,執行緒安全的

       擴充套件筆記:struts1 因為是基於servlet開發的框架,存在安全隱患。所以才催生來後來的struts2(基於filter,擺脫了執行緒安全問題),但技術上二者並無多少聯絡,分別屬於兩個開發團隊。