我们在XPage中有这个基于浏览器的多页面应用程序。主窗口包含5个具有不同页面的框架,第2个(可能还有更多)包含文档,所有文档都具有不同的页面布局。我们以前用“内存中的所有页面”(最初来自R8.5.1)运行应用程序,它闪电般快速但占用内存。我们现在正在将其移至“内存中的一页,其余内容在磁盘上”。
我认为我们现在的情况是:
HashMap是bean内部的一个对象。为什么bean序列化了?我可能会弄错,它可能只是一个不同的HashMap被序列化......
无论如何,我的问题是:我如何同步这些动作,有一些简单的方法吗?
PS我已经尝试使用ConcurrentHashMap,但我得到了一些非常奇怪的结果......
感谢您提供帮助!
答案 0 :(得分:1)
“为什么bean序列化?”默认情况下,sessionScoped bean不会被序列化。如果您使用加载时绑定(例如$ {someBean})或者如果它序列化您可能在加载时绑定中引用的HashMap,例如$ {someBean.someHashMap}(其中$ {是加载时绑定,#{是运行时绑定)。加载时绑定的结果保存在控制树中,当您将服务器端页面保存在磁盘上时,该树将被序列化。那里的解决方案是更改对运行时绑定的引用。
“我该如何同步这些动作” SSJS中有一个synchronized关键字,请参阅: http://mattwhite.me/blog/2009/9/14/on-synchronization-in-xpages.html 但这只能保护对象免受SSJS中的并发访问;页面状态序列化将不会在同一个对象上同步,因此您仍然必须修复它以不对bean和HashMap进行序列化。
答案 1 :(得分:0)
一如遇到这样的错误,你应该问问自己为什么,并阅读文档以了解异常。发生此异常是因为您在迭代时修改了一个集合(例如从中读取)。出于这个确切原因,Java提供了一个名为CopyOfWriteList的集合实现,它允许在读取时进行写入。它通过在写入列表时创建一个新列表(例如复制指针)来完成此操作。当写入频率低于读取时,这很好。遗憾的是,jdk中没有构建地图的东西。
我的建议是封装地图并实现类似功能,以便在新数据上创建新地图。这将使映射对读者不可变,因此将删除并发mod异常。在新数据到达时读取的用户将获得旧的"数据,但它会比同步访问更好。
希望是有帮助的。