是否保证 HttpSessionListener.sessionCreated() 在任何其他线程访问新会话之前完成?

2024-05-02

我正在尝试将值缓存在ConcurrentHashMap in the Session。为了避免竞争条件并确保在任何线程尝试使用我的地图之前创建它,我使用HttpSessionListener.sessionCreated()将地图添加到Session:

@Override
public void sessionCreated(HttpSessionEvent event) {

    event.getSession()
        .setAttribute(MY_CACHE_KEY, new ConcurrentHashMap());

}

这段代码是否保证在任何其他线程访问会话之前完成(通过request.getSession()例如)?

我看了看HttpSessionListener JavaDoc https://javaee.github.io/javaee-spec/javadocs/javax/servlet/http/HttpSessionListener.html#sessionCreated-javax.servlet.http.HttpSessionEvent-Servlet 4.0 规范 https://download.oracle.com/otndocs/jcp/servlet-4-final-eval-spec/index.html而且线程安全似乎没有任何保证。

Serlvet 规范。多次引用会话线程安全性,但据我了解,这些引用都与会话侦听器和会话创建相关:

7.7.1 线程问题

执行请求线程的多个 Servlet 可能会同时主动访问同一会话对象。容器必须确保对表示会话属性的内部数据结构进行操作 以线程安全的方式执行。开发人员有责任对属性对象本身进行线程安全访问。这将保护 HttpSession 对象内部的属性集合免受并发访问, 消除应用程序导致该集合损坏的机会。除非在规范中的其他地方明确说明(例如,第 7.7.1 节,第 7-67 页上的会话对象的“线程问题”),否则必须假定从请求或响应中提供的对象是非线程安全的。这包括但不限于从返回的 PrintWriter ServletResponse.getWriter() 和从 ServletResponse.getOutputStream() 返回的 OutputStream。


11.5 监听器实例和线程

在开始执行应用程序中的第一个请求之前,容器需要完成 Web 应用程序中侦听器类的实例化。容器必须维护对每个侦听器实例的引用,直到为 Web 应用程序提供最后一个请求为止。

ServletContext 和 HttpSession 对象的属性更改可能会同时发生。容器不需要将生成的通知同步到属性侦听器类。维护状态的侦听器类负责数据的完整性,并且应该显式处理这种情况。

似乎很明显sessionCreated()必须在线程访问会话之前完成,但是“明显正确的代码”以前对于多线程来说是不安全的 https://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html.

这种歧义不存在于ServletContextLister.contextInitialized() https://javaee.github.io/javaee-spec/javadocs/javax/servlet/ServletContextListener.html#contextInitialized-javax.servlet.ServletContextEvent-因为它保证在之前完成Servlet初始化和Servlet.init()保证是单线程的并且发生在任何请求之前 https://javaee.github.io/javaee-spec/javadocs/javax/servlet/Servlet.html#init-javax.servlet.ServletConfig-.


我至少测试过 Tomcat,它确实确保了sessionCreated()之前完成request.getSession()返回。我通过放置断点进行测试sessionCreated()并发送一个请求request.getSession()。直到我从断点继续执行该请求才完成。然而,一Servlet容器实现的行为并不能真正证明所有容器/服务器都以这种方式运行。


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否保证 HttpSessionListener.sessionCreated() 在任何其他线程访问新会话之前完成? 的相关文章

  • 从 Spring MVC XML 文件转移到 javaconfig。我真的对我的数据库 XML 文件感到困惑

    我从 Spring MVC XML 文件转移到 javaconfig 我真的对我的数据库 XML 文件感到困惑 我不知道如何让 Hibernate4 工作以及我的 JBoss JNDI 数据源工作 有人可以告诉我如何使 javaconfig
  • Spring中的ProxyFactoryBean

    有人可以解释一下吗代理工厂Bean http static springsource org spring docs current javadoc api org springframework aop framework ProxyFa
  • 本地开发的 Azure Functions 扩展包版本问题

    我有一个带有队列触发器的 Java 11 Azure 函数 该函数在部署到 Azure 时按预期工作 并正确从定义的服务总线主题中提取消息 但是 运行相同的功能locally除非我回滚版本 否则不起作用Azure Functions 绑定扩
  • JUnit5 平台启动器 API - 如果没有至少一个测试引擎,则无法创建启动器

    我正在尝试升级我们的自动化测试套件的测试能力以接受 JUnit5 测试并遵循JUnit 平台启动器 API 说明 https junit org junit5 docs current user guide launcher api我收到错
  • 这个等待通知线程语义的真正目的是什么?

    我刚刚遇到一些代码 它使用等待通知构造通过其其他成员方法与类中定义的线程进行通信 有趣的是 获取锁后 同步范围内的所有线程都会在同一锁上进行定时等待 请参见下面的代码片段 随后 在非同步作用域中 线程执行其关键函数 即 做一些有用的事情1
  • 从 Invoke 方法获取 RETURN

    我正在尝试从另一个线程上的列表框项目中读取值 我尝试创建一种新方法来运行调用命令 我可以设法将命令发送到列表框 例如通过调用方法添加 但我似乎无法得到响应 我似乎无法获取该项目的值 我尝试了几种方法 一旦我将它从空变为字符串 事情就开始变得
  • 如何将 Java 地图转换为在 Scala 中使用?

    我正在开发一个 Scala 程序 该程序调用 Java 库中的函数 处理结果并生成 CSV 有问题的 Java 函数如下所示 Map
  • 在grails控制器中识别ajax请求或浏览器请求

    我正在开发一个使用大量ajax的grails应用程序 如果请求是ajax调用 那么它应该给出响应 这部分正在工作 但是如果我在浏览器中输入URL 它应该带我到主页 索引页面而不是请求的页面 下面是ajax调用的示例gsp代码
  • Java:SortedMap、TreeMap、可比较?如何使用?

    我有一个对象列表 需要根据其中一个字段的属性进行排序 我听说 SortedMap 和 Comparator 是实现此目的的最佳方法 我是否要与正在排序的类实现 Comparable 还是创建一个新类 如何实例化 SortedMap 并传入
  • Struts 1 到 Spring 迁移 - 策略

    我有一个legacy银行应用程序编码为Struts 1 JSP现在的要求是迁移后端 目前为 MVC to Springboot MVC 后续UI JSP 将迁移到angular Caveats 1 后端不是无状态的 2 会话对象中存储了大量
  • Facebook API - fql_query,无效会话

    我正在尝试使用 PHP 库查询 Facebook 我读到的内容不应该需要会话密钥 或者更确切地说 对于我的情况 它不应该需要会话密钥 但下面的代码给出了以下错误 Session密钥无效或不再有效 http wiki developers f
  • 如何在 JPA 和 Hibernate 中将数据库生成的列值定义为只读字段?

    使用 MariaDB 10 2 可以定义日期时间的默认值 例如创建和最后修改 我应该如何将此列作为只读字段访问 因为这个值应该只在数据库的控制之下 并且不应该从代码中修改 但我想在代码中读取这个属性 这很简单 只需设置insertable
  • 正确签名的 JNLP 应用程序无法在 Java 7 中运行

    我有一个 JNLP 应用程序 由于证书过期需要更新 我有一个经过 CA 验证的新证书 我已将新证书导入到我的密钥库中 我已导入完整的证书链 我的构建文件对构建中的 jar 进行签名和时间戳
  • 在 Java 中创建 XML 文件的最佳方法是什么?

    我们目前使用 dom4j 来创建 XML 文件 不过 我猜现在有更好的东西了 如果我们使用的是 Java 1 6 或更高版本 那么在编写 XML 文件时最好使用什么类 运行速度最快 使用简单 我不需要构建一个 DOM 然后编写整个 DOM
  • 如何减去两个 XmlGregorianCalendar 对象来创建一个 Duration 对象?

    我想计算两个时间之间的差值XmlGregorianCalendar对象 从而创建一个Duration object 但我还没有找到执行减法的干净方法 你会怎么做 那应该是 DatatypeFactory newDuration xgc2 t
  • 删除 JFX 中选项卡后面的灰色背景

    So is there any way to remove the gray area behind the tab s 我尝试过用 CSS 来做到这一点 但没有找到方法 要设置 tabpane 标题的背景颜色 请在 CSS 文件中写入 t
  • Collections.sort(list) 和 list.sort(Comparator) 之间的区别

    有什么理由让我应该选择Collections sort list 方法而不是简单地调用list sort 内部Collections sort只是调用sort的方法List无论如何 上课 令人惊讶的是几乎每个人都告诉我使用Collectio
  • Axis2 错误:要输出的文本中的空白字符 (0x4) 无效

    我创建了一个 Java 客户端 使用 Axis2 1 7 6 作为代码生成器与 SOAP Web 服务进行交互 问题在于客户端的某些输入抛出异常并显示以下消息 org apache axis2 AxisFault Invalid white
  • 如何建立与 FileZilla Server 1.2.0 的 FTPS 数据连接

    使用 Apache commons net 的 Java FTPSClient 进行会话恢复是一个已知问题 会话恢复是 FTPS 服务器数据连接所需的一项安全功能 Apache FTPSClient 不支持会话恢复 并且 JDK API 使
  • Java中单例的其他方式[重复]

    这个问题在这里已经有答案了 只是我在考虑编写单例类的其他方法 那么这个类是否被认为是单例类呢 public class MyClass static Myclass myclass static myclass new MyClass pr

随机推荐