LoadableDetachableModel多线程问题

时间:2016-05-25 17:13:17

标签: java multithreading wicket

我们遇到一个问题,很多用户都在点击一个有很多ajax调用的页面。我们花了很长时间才倒闭,最后在LoadableDetachableModel中发现了一个线程问题。

我认为问题与我们在Session中有UserModel的事实有关。此UserModel扩展了LoadableDetachableModel。如果load()方法返回时间过长,那么第二个Thread可能会获得null用户返回的基于以下事实:在调用load()之前和设置transientModelObject之前,附加标志设置为true。为了解决这个问题,我们只需创建自己的LoadableDetachableModel修改版本,在必要时添加同步。从那以后我们就没有问题了。

我在Wicket Jira网站环顾四周,甚至看了一些鱼眼内部的提交,看看这个问题是否已经修复,因为我注意到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且状态不是DETACHED。

同样,我认为只有在Session或Application类中使用LoadableDetachableModel时才会发生这种情况,其中多个线程可以重用相同的模型。

我错过了什么或者我应该提交错误报告吗?我不应该在Session中使用LoadableDetachableModel吗?

1 个答案:

答案 0 :(得分:3)

IModel是Components使用的接口,所有组件都是单线程的。 不要在会话或应用程序中使用模型。