我们知道,一个Servlet对应一个Servlet实例,也就是说Servlet是单例的,那么就有可能会出现一个Servlet同时处理多个不同的请求,这时就可能会出现线程不安全问题。如何防止出现线程安全问题,有以下三种方法:
- 不要在Servlet中创建成员变量,可以创建局部变量;
- 如果要创建成员变量,必须保证是无状态的成员变量;
- 如果创建的有状态的成员变量,状态必须是只读的。
下面我们通过案例来说明以上两种方法,具体如下:
- 在Servlet中创建无状态的成员变量。
- 在web应用Example13中新建一个User.java类,具体代码如例1-1所示:
例1-1 User.java
package cn.itcast.domain;
public class User {
public void say(){
System.out.println("hello world!");
}
}
例1-1所示,User类中没有成员变量,只有一个say()方法。
- 再次新建一个Servlet,名字为SafeServlet,它有一个User类型的成员变量,如例1-2所示:
例1-2 SafeServlet.java
import cn.itcast.domain.User;
public class SafeServlet extends HttpServlet {
private User user=new User();
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
例1-2中,SafeServlet中虽然有成员变量user,但是User类中并没有成员变量,所以称user是无状态的,多个线程同时访问时,不会出现线程安全问题。
(2)在Servlet中创建状态为只读的成员变量。
- 修改User类,为它添加一个成员,具体代码如例1-3所示:
例1-3 User.java
package cn.itcast.servlet;
public class User {
private String name="zhangsan";
public String getName() {
return name;
}
public void say(){
System.out.println("hello world!");
}
}
例1-3中,User类有了成员变量,而且为该成员变量提供了get方法,那么对于SafeServlet来说,它的成员user就是有状态的,而且状态是只读的。同一时刻,多个线程同时访问时,因为都只能对该成员进行读操作,不能进行写操作所以各个线程之间就不会互相影响了。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/253101.html