struts2中每个action有多个实例,处理一次请求就会生成一个实例,这些实例彼此独立,处理完毕就会销毁。因此每个action是线程安全的。 servlet是单例模式的,只会产生一个实例,当多个用户同时请求一个servlet的时候,tomcat就会派生出多个线程来执行servlet的代码,因此servlet是线程不安全的。
package servletThread; 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 ThreadSafeServlet extends HttpServlet{ private String name; //定义一个公共的私有变量 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub resp.setContentType("text/html"); name=req.getParameter("name"); try { Thread.sleep(10000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } resp.getWriter().print("name:"+name); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doPost(req, resp); } }我们十秒钟内用浏览器访问ThreadSafeServlet?name=”zhangSan”和ThreadSafeServlet?name=”lisi”,显示结果均为name=”lisi”,这时候就是线程不安全。 解决方式: 1.将全局变量name定义为final类型,final类型修饰的变量为常量,这表示在servlet中只进行读操作,读操作不会出现线程安全的问题。 2.将name定义为全局变量,这时每个线程没有争用资源。