这个Servlet是线程安全的吗?

情况:

言简意赅的描述下,程序框架是这样的 servelt -> service -> DAO -> Database

现在的问题就是不确定在多用户并发访问的情况下servlet是否是线程安全的?也就是说会不会出现用户得到的数据互相混乱的情况(这是相当糟糕的=_ =。。。)

大概的伪代码图如下:

User (POJO对象)
===============================
int userid
Stirng username
String password
// getter and setter method

UserDao (DAO数据访问对象,里面的方法用hibernate写的)
===============================
add(User)
delete(User)
update(User)
List find(int)
{
//……get from data base
}

UserService (往上封装的服务类,会存一个dao的实例对象)
===============================
UserDao userDao = new UserDao();
——————————-
add(User)
delete(User)
update(User)
find(int userid)
{
List list = userDao.find(userid)
}

UserServlet (servlet类,会存一个UserService的实例变量)
================================
UserService userService = new UserService();
——————————–
doPost(request,response)
{
String userid = request.getParameter(“userid”);
User user = userService.find(userid);
response.getWriter().write(user.getUsername());
response.getWriter().close();
}

图解:

类名
===========
实例变量
———–
方法

问题:
servlet中打印出来的username在多线程下会不会出现混乱的情况?也就是我的userid发送请求回来的不是我对应的username,而是别人的?
response.getWriter().write(user.getUsername());

答:

需要考虑同步的前提是:有共享的资源
这个servlet完全没有共享的东西,比如实例变量之类的。实例变量是实例所有的,在堆中分配。在Servlet/JSP容器中,一般仅实例化一个Servlet/JSP实例,启动多个该实例的线程来处理请求。而实例变量是该实例所有的线程所共享,所以,实例变量不是线程安全的。局部变量在堆栈中分配,因为每一个线程有自己的执行堆栈,所以,局部变量是线程安全的。所以这个例子不需要考虑同步问题。

无状态对象都是线程安全的。

推荐看《JAVA并发编程实践》

(以上答案来自byr论坛的童鞋们,太感谢你们答疑解惑了:))

Leave a Comment.