如果两个线程在服务器上访问此方法,它是否是线程安全的?线程来自GWT计时器。
public UserDTO getUserFromSession()
{
UserDTO user = null;
HttpServletRequest httpServletRequest = this.getThreadLocalRequest();
HttpSession session = httpServletRequest.getSession();
Object userObj = session.getAttribute("user");
if (userObj != null && userObj instanceof UserDTO)
{
user = (UserDTO) userObj;
}
return user;
}
答案 0 :(得分:2)
如果方法不能访问外部(方法)共享变量,则该方法是线程安全的。
代码中的问题可能出在那行代码中:
HttpServletRequest httpServletRequest = this.getThreadLocalRequest();
因为this.getThreadLocalRequest()
似乎访问共享变量。
为了确保发表全班,但我能看到的是不是线程安全的。
在解释说明getThreadLocalRequest
方法安全返回HttpServletRequest
的注释之后,代码仍然不是线程安全的。
根据此article,事实HttpSession
不是线程安全的:基本上会话可以在代码执行期间更改。
例如,您也可以在会话失效后返回用户。
想象一下这个步骤:
thread 1 thread 2
---------------------------------------------- --------------
Object userObj = session.getAttribute("user");
session.invalidate();
if (userObj != null && userObj instanceof UserDTO) {
user = (UserDTO) userObj;
}
return user;
如果会话被另一个线程无效,那么最后您也会返回一个用户。
答案 1 :(得分:0)
这种方法本身是无害的。即使您没有线程本地请求,它也将是无害的。我看到的唯一问题是在实例化时检索属性“user”的关闭情况,另一个线程在第一个线程退出方法之前擦除属性“user”clean。您将在一个线程中处理用户实例,而在另一个线程中,由于不再定义“user”属性,您可能会以不同方式执行逻辑。
那就是说,我真诚地怀疑会出现任何问题,因为这些都是读取和不写入而没有副作用的方法。请注意,有几个线程可能(并且可能会)处理相同的用户实例,因此在这种情况下,您需要在同步块下对用户保持线程敏感操作。
答案 2 :(得分:0)
是的,就只有你给定的方法而言,它是线程安全的。
getThreadLocalRequest()
是您当前线程的本地线程,getSession()
也是线程安全的。
即使从会话中获取userObj
也不会导致问题。
但毕竟多次调用可以访问相同的UserDTO
对象。
因此,您需要确保此对象中的可能更改以线程安全方式完成,或者该对象是不可变的。
答案 3 :(得分:0)
该方法看似线程安全,但它不是,但是以更微妙的方式:
虽然getSession()
和会话是安全的,但会话及其内容不是。
您正在寻找的会话可以随时消失。仅检查此方法是不够的,还要检查所有其他会话相关对象。
在高负载情况下,您需要注意,getuser函数不会动态重新创建会话。
getSession(false)
将负责此事。在这种情况下,您将对返回的会话进行空检查并中止您的通话。
之前由其他人声明的用户对象是另一项责任。