[J2EE] Servlet執行緒不安全的體現以及解決方式 筆記
阿新 • • 發佈:2018-12-15
對於例項變數來說,由於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。這個就是高併發下的多執行緒的安全問題。
解決方式:
- 新增同步程式碼鎖 synchronized
- 將要訪問的例項變數改為區域性變數(多執行緒下每個執行緒對區域性變數都會有自己的一份copy,這樣對區域性變數的修改只會影響到自己的copy而不會對別的執行緒產生影響,執行緒安全的
擴充套件筆記:struts1 因為是基於servlet開發的框架,存在安全隱患。所以才催生來後來的struts2(基於filter,擺脫了執行緒安全問題),但技術上二者並無多少聯絡,分別屬於兩個開發團隊。