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定义为全局变量,这时每个线程没有争用资源。