java是HttpSession线程安全的,设置/获取属性是线程安全的操作吗?
另外,被设置的对象是否必须是线程安全的,以确保我们知道会话中存储的对象的状态是已知的
此外,我在网上看到一些人建议使用:
synchronized(session) {
session.setAttribute("abc", "abc");
}
这是一个有效的建议吗
你可以在下面搜索框中键入要查询的问题!
另外,被设置的对象是否必须是线程安全的,以确保我们知道会话中存储的对象的状态是已知的
此外,我在网上看到一些人建议使用:
synchronized(session) {
session.setAttribute("abc", "abc");
}
这是一个有效的建议吗
# 1 楼答案
不需要。因为您不希望同一个客户端(带有会话)执行并发请求,所以应该像Spring MVC中的AbstractController那样序列化这些请求
# 2 楼答案
会话不是线程安全的,get和set方法都不能保证线程安全。通常,在servlet容器中,您应该假设处于多线程环境中,并且没有提供安全的工具
这也适用于存储在会话中的对象。会话本身不会操作存储的对象,但您可以在不同的线程中检索对象并尝试操作它。这取决于您检查自己的代码,看看是否可能存在竞争条件
您发布的代码示例是有效的,但问题可能超出了示例的有限范围。它确保在设置会话时不存在任何条件,但不会阻止其他线程重写该设置。如果请求中的代码依赖于保持不变的值,那么您仍然可能遇到麻烦
# 3 楼答案
在某些方面,这取决于您的客户机设计
在您的web设计中,您是否有机会使用同一HTTP会话使单个客户端同时具有多个未完成的请求?这似乎很难做到,除非将一个HTTP会话绑定到多个套接字。(AJAX)如果不这样做,就服务器而言,给定客户端的HTTP访问将是单线程的,这意味着单会话实际上是线程安全的
会话对象的同步将使应用程序更安全,以防将来的更改使web应用程序能够同时发出多个请求,因此这不是一个坏主意。在现代Java实现中,同步没有以前与之相关的巨大成本,特别是在同步通常是无争用的情况下。如果您的应用程序使用AJAX,这意味着您希望对web服务器同时发出多个飞行中的请求,那么同步是必须的
# 4 楼答案
Servlet 2.5规范:
这是安全的:
这是不安全的:
这不是保证安全的:
我见过最后一种方法(包括在J2EE书籍中),但Servlet规范并不保证它能工作。您可以use the session ID to create a mutex,但必须有更好的方法
# 5 楼答案
它们不是,但大多数情况下,您的客户机只能通过单个线程访问它们
不同的客户端将有不同的线程,每个客户端都有自己的会话
正如Eddie指出的,您可能会遇到两个线程访问同一会话的情况,即两个ajax调用试图修改同一会话属性。否则你就不会有问题了
# 6 楼答案
不,根据IBM的说法,它们不是线程安全的。你需要同步
爪哇牧场的How HttpSession is not thread safe可能也会有帮助