HttpSession 线程安全吗?set/get Attribute 操作是否线程安全?
另外,正在设置的对象是否必须是线程安全的,以保证我们知道会话中存储的对象的状态是已知的。
另外,我在网上读到有人建议使用:
synchronized(session) {
session.setAttribute("abc", "abc");
}
这是一个有效的建议吗?
Also, does the object that is being set have to be thread safe in order to guarantee that we know what the state of the object stored in session is known.
Also, I was reading on the web that some suggest using:
synchronized(session) {
session.setAttribute("abc", "abc");
}
Is this a valid suggestion?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Servlet 2.5 规范:
这是安全的:
这是不安全:
这是不保证安全的:
我已经看到最后一种提倡的方法(包括在J2EE书籍中),但不能保证按照 Servlet 规范工作。 您可以使用会话 ID 创建互斥锁,但一定有更好的方法。
Servlet 2.5 spec:
This is safe:
This is not safe:
This is not guaranteed to be safe:
I have seen this last approach advocated (including in J2EE books), but it is not guaranteed to work by the Servlet specification. You could use the session ID to create a mutex, but there must be a better approach.
不。并且由于您不希望同一客户端(带有会话)执行并发请求,因此您应该像 AbstractController 在 Spring MVC 中执行
No. And since you don't want the same client (with session) to be doing concurrent requests, you should serialize these requests like the AbstractController does in Spring MVC
在某些方面,这取决于您的客户端设计。
在您的网页设计中,您是否有机会让单个客户端使用同一 HTTP 会话同时处理多个未完成的请求? 除非将单个 HTTP 会话绑定到多个套接字,否则这似乎很难做到。 (又名 AJAX)如果不这样做,就服务器而言,给定客户端的 HTTP 访问将是单线程的,这意味着单个会话实际上是线程安全的。
会话对象的同步将使应用程序更安全地应对未来的更改,使您的 Web 应用程序能够同时处理多个请求,因此这不是一个坏主意。 在现代 Java 实现中,同步没有以前与之相关的巨大成本,特别是当同步通常是无竞争的时。 如果您的应用程序使用 AJAX,这意味着您希望向 Web 服务器发送多个正在进行的并发请求,那么同步是必须的。
In some ways, this depends on your client design.
Do you have the opportunity, in your web design, for a single client to have multiple outstanding simultaneous requests using the same HTTP session? This seems difficult to do unless you tie a single HTTP session to multiple sockets. (aka, AJAX) Short of doing this, a given client's HTTP access will be single-threaded as far as the server is concerned, which means a single session is effectively Thread safe.
Synchronization of your session objects will make the application safer against future changes that make your web application capable of having multiple simultaneous requests, so it's not a bad idea. In modern Java implementations, synchronization does not have the large cost that was previously associated with it, especially when the synchronization is usually uncontended. If your application uses AJAX, which implies that you expect multiple in-flight simultaneous requests to your web server, then synchronization is a must.
它们不是,但大多数时候,您的客户端只能通过单个线程访问它们。
不同的客户端将有不同的线程,每个线程都有自己的会话。
正如 Eddie 指出的,您可能面临两个线程访问同一会话的一种情况是两个 ajax 调用试图修改同一会话属性。 否则你不会有问题。
They are not, but most of the times, your clients will only access them with a single thread.
Different clients will have different threads and each one will have its own Session.
As Eddie points out, one situation where you may face two thread accessing the same session is two ajax calls are attempting to modify the same session attribute. Otherwise you won't have problems.
会话不是线程安全的,并且 get 和 set 方法都不能保证线程安全。 一般来说,在 servlet 容器中,您应该假设处于多线程环境中,并且没有提供的工具是安全的。
这也适用于您在会话中存储的对象。 会话本身不会操作存储的对象,但您可以在不同的线程中检索该对象并尝试操作它。 您可以检查自己的代码以查看竞争条件是否可能。
您发布的代码示例是有效的,但问题可能超出了示例的限制范围。 它确保在设置会话时不存在任何条件,但没有任何东西可以阻止其他线程覆盖该设置。 如果您请求中的代码取决于保持不变的值,您仍然可能遇到麻烦。
The session is not thread safe and neither the get not the set methods are guaranteed to be thread safe. In general in a servlet container you should assume to be in a multi threaded environment and no provided tooling is safe.
This also goes for the objects you store in the session. The session itself will not manipulate the stored object but you can retrieve the object in different thread and attempt to manipulate it. It is up to you to examine your own code to see if race conditions are possible.
The code example you posted is valid, but the problem may exist beyond the limited scope of your example. It assures there are no conditions while setting to the session, but there is nothing preventing an other thread to override the set. If the code in your request depends of the value remaining unchanged you could still be in trouble.