Portlet、HttpSession 和线程安全

发布于 2024-10-25 21:34:38 字数 729 浏览 2 评论 0原文

我们的 portlet 将状态保存在 HttpSession 中,该状态由同一会话的所有请求处理线程共享。

portlet 规范 (JSR-168) 写道:

PLT.5.2.4.3 请求处理期间的多线程问题

Portlet 容器通过并发处理对同一个 Portlet 的并发请求 在不同线程上执行请求处理方法。 Portlet 开发人员必须 设计他们的 portlet 来处理来自多个线程的并发执行 任何特定时间的 processActionrender 方法。

我想知道我应该如何实现这一目标?当然,我可以在 processActionrender 期间使用同步来实现互斥,但我不知道如何强制整个请求处理的原子性。特别是,我担心以下情况:

  • 线程 1 执行 processAction,将数据加载到会话中以供稍后渲染
  • 线程 2 执行 processAction,丢弃会话中的数据
  • 线程 1执行render,从会话中读取要渲染的数据,并抛出 NullPointerException,因为准备好的数据不再存在......

通常如何防止这种情况?特别是,当使用 JBoss Portlet 桥来使 JSF 适应 Portlet 环境时?

Our portlets keep state in the HttpSession, which is shared by all request processing threads for the same session.

The portlet spec (JSR-168) writes:

PLT.5.2.4.3 Multithreading Issues During Request Handling

The portlet container handles concurrent requests to the same portlet by concurrent
execution of the request handling methods on different threads. Portlet developers must
design their portlets to handle concurrent execution from multiple threads from within the
processAction and render methods at any particular time.

I wonder how I am supposed to achieve that? Sure, I can use synchronization to achieve mutual exclusion during both processAction and render, but I don't see how I can enforce atomicity of request processing as a whole. In particular, I worry about the following scenario:

  • Thread 1 executes processAction, loading data into the session for later rendering
  • Thread 2 executes processAction, discarding that data from the session
  • Thread 1 executes render, reading the data to render from the session, and throws a NullPointerException because the prepared data is no longer there ...

How is that scenario usually prevented? In particular, when using the JBoss portlet bridge to adapt JSF to a Portlet environment?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不打扰别人 2024-11-01 21:34:39

我想说,如果有两个 portlet 操作相同的数据,尤其是一个读取它,而另一个删除它,那么设计中很可能存在严重缺陷。

然后,您可能想要存储每个 portlet/线程的数据,即,如果 portlet1 读取一些数据,您应该写入锁定它,直到读取完成,然后使用唯一密钥将其放入会话中。

如果删除应渲染的数据是合法的,那么您应该考虑到这一点并在渲染期间再次检查。

I'd say that if there are two portlets operating on the same data, especially one reading it while the other deletes it, there's most likely a serious flaw in the design.

You might then want to store the data per portlet/thread, i.e. if portlet1 reads some data you should write lock it until reading is finished and put it into the session using a unique key.

If it is legal to delete data that should be rendered, then you should account for that and check again during render.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文