使用servlet进行开发项目,在面临高并发时,会出现线程不安全问题;
Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。
当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。
链接:http://www.runoob.com/servlet/servlet-life-cycle.html
解决办法:
一、如何防止变量的线程安全:
1、把全局变量改为局部变量
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
{
String userName=request.getParameter("userName");
PrintWriter out=response.getWriter();
if(userName!=null&&userName!="")
{
out.print(userName);
}
else {
out.println("用户名不存在");
}
}
因为每次调用这个方法的时候就会重写对userName实例化这样一来就不会存在线程安全问题了。
2、使用synchronized对doGet进行同步
protected synchronized void doGet(HttpServletRequest request, HttpServletResponse response)
采用这种方式明显不合适,因为这样T2必须要等T1执行完毕以后才可以执行,大大的影响了效率。
3.如果是静态资源则加上final表示这个资源不可以改变
比如 final static String url=“jdbc:mysql://localhost:3306/blog”;
4:总结
1:只要我们了解Servlet容器工作的模式,可能就能够理解为什么Servlet会出现线程安全问题,所以一定牢记Servlet容器是多线程单实例的模型
2:避免使用全局变量,最好是使用局部变量,其实这本身也是一个好的编程习惯
3:应该使用只读的实例变量和静态变量(就是前面加上final意为不可改变)
4:不要在Servlet上自己创建线程,因为Servlet容器已经帮我们做好了。
5:如果要修改共享对象的时候记得要同步,尽量缩小同步的范围(比喻修改Session时候直接使用synchronized(Session)即可),避免影响性能