我们遇到了一个问题,即许多用户访问的页面上有大量 ajax 调用。我们花了很长时间跑下来,终于在LoadableDetachableModel中发现了线程问题。
我认为问题与我们在 session 中有一个 UserModel 有关。此 UserModel 扩展了 LoadableDetachableModel。如果 load() 方法返回时间太长,则第二个线程可能会返回 null User,因为附加标志在调用 load() 之前和设置 transient 模型对象之前设置为 true。为了解决这个问题,我们简单地制作了自己的 LoadableDetachableModel 修改版本,在必要时添加了同步。从那时起我们就没有再遇到任何问题。
我环顾了 Wicket Jira 网站,甚至查看了 Fisheye 中的一些提交,看看这个问题是否已得到解决,因为我注意到 Wicket 7 没有附加标志。相反,它有一个名为 InternalState 的枚举来修复 WICKET-5916。看来线程问题在 7.2 版本的 wicket 中仍然存在。这是代码:
@Override
public final T getObject()
{
if (state == null || state == InternalState.DETACHED)
{
// prevent infinite attachment loops
state = InternalState.ATTACHING;//<--One thread sets this, next thread gets a null object returned since load() has not completed
transientModelObject = load();
if (log.isDebugEnabled())
{
log.debug("loaded transient object " + transientModelObject + " for " + this +
", requestCycle " + RequestCycle.get());
}
state = InternalState.ATTACHED;
onAttach();
}
return transientModelObject;
}
如您所见,如果单个线程调用 getObject() 并到达调用 load() 的行,则模型的状态变量设置为 ATTACHING。现在,下一个线程在 load() 完成之前调用 getObject() 并获取返回的 null 对象,因为 state 不为 null 并且 state 不是 DETACHED。
同样,我认为只有当您在 Session 或 Application 类中使用 LoadableDetachableModel 时才会发生这种情况,其中多个线程可以重用同一模型。
我是否遗漏了什么或者我应该提交错误报告?我不应该在 session 中使用 LoadableDetachableModel 吗?
最佳答案
IModel是组件使用的接口(interface),所有组件都是单线程的。 不要在 session 或应用程序中使用模型。
关于java - LoadableDetachableModel 多线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37443700/