简体   繁体   English

根据Java,此方法线程安全吗?

[英]Is this method thread safe according to Java

If two threads are accessing this method on server, will it be thread safe? 如果两个线程正在服务器上访问此方法,那么它是线程安全的吗? The threads are coming from GWT timer. 线程来自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;
}

A method is thread safe if it doesn't access to external (to the method) shared variables. 如果方法不访问外部(方法)共享变量,则该方法是线程安全的。

The problem in your code could be on that line of code: 您的代码中的问题可能在该行代码上:

HttpServletRequest httpServletRequest = this.getThreadLocalRequest();

because this.getThreadLocalRequest() seems to access a shared variable. 因为this.getThreadLocalRequest()似乎访问共享变量。 To be sure post the whole class, but for what I can see it is not thread safe . 可以肯定的是,在整个课程之后,但就我所知,它不是线程安全的


Also after the comment that explain what getThreadLocalRequest method returns a HttpServletRequest safely the code remains not thread safe. 同样在解释什么getThreadLocalRequest方法安全返回HttpServletRequest的注释之后,代码仍然不是线程安全的。

Infact HttpSession is not thread safe according to this article : basically the session can change during the code execution. 根据本文,实际上HttpSession不是线程安全的:基本上,会话可以在代码执行期间更改。 For example you can return the user also after an invalidation of the session. 例如,您也可以在会话无效后返回用户。 Imagine this steps: 想象一下以下步骤:

thread 1                                                thread 2
----------------------------------------------          --------------
Object userObj = session.getAttribute("user");

                                                        session.invalidate();

if (userObj != null && userObj instanceof UserDTO) {
    user = (UserDTO) userObj;
}
return user;    

At the end you return a user also if the session was invalidated by another thread. 最后,如果会话被另一个线程无效,则还返回一个用户。

This method in of itself is harmless. 这种方法本身是无害的。 It would be harmless even if you did not have a thread local request. 即使您没有线程本地请求,这也将是无害的。 The only problem with it I see is the off case in which you retrieve attribute "user" while it is instantiated, and another thread wipes attribute "user" clean before the first thread can exit the method. 我看到的唯一问题是关闭的情况,在这种情况下,您在实例化属性“ user”时检索该属性,而另一个线程在第一个线程可以退出该方法之前将属性“ user”清除了。 You'd be dealing with a user instance in one thread and in the other, you might be performing logic differently due to the fact that "user" attribute is no longer defined. 您将在一个线程中处理一个用户实例,而在另一个线程中,由于不再定义“ user”属性,因此您执行逻辑的方式可能有所不同。

That said, I sincerely doubt that any problems would arise since these are all methods that read and don't write with no side effects. 就是说,我衷心怀疑是否会出现任何问题,因为这些都是读取和写入的方法,没有副作用。 Just be mindful of the fact that several threads could be (and probably will be) handling the same instance of user so you'll want to keep thread-sensitive operations on user under a synchronized block in that case. 请注意以下事实:多个线程可能(并且可能会)处理同一用户实例,因此在这种情况下,您需要将对用户线程敏感的操作保持在同步块下。

Yes, it is threadsafe as far as only your given method is concerned. 是的,就您给定的方法而言,它是线程安全的。 getThreadLocalRequest() is local to your current thread and getSession() is threadsafe as well. getThreadLocalRequest()在当前线程本地,而getSession()也是线程安全的。 Even getting the userObj from the session should not cause issues. 即使从会话中获取userObj也不会引起问题。

But after all multiple calls could access the same UserDTO object. 但毕竟所有多个调用都可以访问同一个UserDTO对象。 Therefore you need to make sure that either possible changes in this object are done in a threadsafe way or that the object is immutable. 因此,您需要确保以线程安全的方式对这个对象进行可能的更改,或者该对象是不可变的。

the method looks threadsafe but it isn't, but in a more subtile way: 该方法看起来是线程安全的,但不是,而是以更微妙的方式:

While getSession() and Session is safe, the session and its contents are not. 尽管getSession()和Session是安全的,但session及其内容不是。

The Session you were looking for can go away anytime. 您要查找的会话可以随时消失。 It is not enough to examine only this method, but all other session dependent objects as well. 仅检查此方法还不够,仅检查所有其他依赖于会话的对象也是不够的。

In a high load situation, you need to take care, that your getuser function will not recreate the session on the fly. 在高负载的情况下,您需要注意,getuser函数不会即时重新创建会话。

getSession(false) will take care of this. getSession(false)会解决这个问题。 You will have a null check on the Session returned and abort your call in that case. 您将对返回的会话进行空检查,并在这种情况下中止通话。

The user object as stated by others before is another responsibility. 之前其他人指出的用户对象是另一种责任。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM