struts2學習筆記–執行緒安全問題小結

冬至飲雪發表於2016-02-05

    在說struts2的執行緒安全之前,先說一下,什麼是執行緒安全?這是一個網友講的,

  如果你的程式碼所在的程式中有多個執行緒在同時執行,而這些執行緒可能會同時執行這段程式碼。如果每次執行結果和單執行緒執行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是執行緒安全的。

    就是說,在一個程式中有多個執行緒併發執行,每個執行緒執行過程中,變數值是相同的,執行結果也是相同的,就是執行緒安全的.否則就是執行緒不安全的.

    然後回顧一下servlet的執行緒安全問題,由於servlet是單例模式的,只會產生一個例項,當多個使用者同時請求一個servlet的時候,Tomcat會派生出多個執行緒來執行servlet的程式碼,因此servlet是執行緒不安全的,如果使用不當,可能會出現問題.下面貼一個例子:

package com.wang.servlet;

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

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

public class ThreadSafeServlet extends HttpServlet {

    private  String name;//定義一個公共的私有變數 name
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html");
        //從request域中獲取name屬性
        name =request.getParameter("name");
        //使執行緒休眠10秒
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //向瀏覽器輸出name的值
        response.getWriter().print("name="+name);
    }

}

 

    我們在十秒內分別用兩個瀏覽器訪問ThreadSafeServlet?name=”zhangSan”和ThreadSafeServlet?name=”liSi”,顯示的結果均為name=liSi,這就意味著程式出現了問題,多執行緒併發的讀寫會導致資料不同步的問題,所以我們在使用servlet的時候儘量不要定義全域性的私有屬性,而是把變數分別定義到doGet()和doPost()方法中去,當然如果僅僅是讀操作,是不會出現問題的,因此如果要在servlet中定義全域性的只讀屬性最好定義為final型別.

  Struts2中的Action為每個請求都建立一個例項,Action和普通的java類沒有任何區別,不會出現資料不同步的情況,因此是執行緒安全的,


相關文章