2011-11-15 34 views
0

我有一个Vaadin应用程序,并且在同时运行应用程序的两个实例(一个在FF中,另一个在IE中)时出现一些奇怪的行为。我已经删除了大部分静态对象(这些导致应用程序在与另一个打开的应用程序并行使用时完全重新加载),现在我可以正常与UI进行交互,而无需完全重置。但是,我现在注意到,我在这两个界面中只获取一个用户的数据。我认为这是由我用来管理一些数据缓存和一个SOAP连接的单例对象引起的。我想知道是单引擎模式本身导致了奇怪的输出,还是只是我保留的静态实例对象?如何防止vaadin应用程序实例干扰彼此?

我尝试过使用ThreadLocal与我的单例,但所有我的变量总是空,当我尝试使用它们在我的单身人士的功能。目前我的单身人士包含这个,这可能是非常错误,因为它不起作用。

private static ThreadLocal<SoapClient> instance = new ThreadLocal<SoapClient>(); 

public static synchronized SoapClient getInstance(){ 
    if (instance.get() == null) { 
     instance.set(new SoapClient()); 
    } 
    return instance.get(); 
} 

我选择了一个单独的对象,所以我就会一直访问缓存数据和我的用户的SOAP连接无处不在我的应用程序实例,我可以做这件事想到的唯一另一种方法是有一个静态对象的地方,但静态关键字似乎首先是我所有问题的原因。有没有办法解决这个问题,或者是否有其他方法导致它?

回答

4

一种更好的方式来实例线程局部会是这样

ThreadLocal<SoapClient> instance = new ThreadLocal<String>() { 
    @Override 
    protected String initialValue() { 
    return new SoapClient();  
    } 
} 

然而,你的问题就在这里是Web应用程序服务器“池”,并重新使用线程。在Vaadin术语中,并非针对应用程序的每个请求都被处理为相同的线程 - 即Thread1可以处理App实例1和App Instance 2的请求。如果SoapClient缓存适用于App实例1的信息,则App 2的UI可能会最终使用该SoapClient的为App 1

假设(从你的描述)认为,“应用程序的特定”信息在SoapClient的缓存,我建议你

  • 创建并存储在您的SoapClient的应用程序对象上一个正常的字段(不是静态的,不是threadlocal)

  • 如果你需要访问应用程序(为了获得SoapClient),并且从你所在的位置来看很复杂,请使用ThreadLocal access pattern。请参阅链接上的第二个示例。请注意,ThreadLocal设置在HttpRequest的开头,最后设置为“unset”,以确保同一线程上的任何后续请求都不会获得相同的应用程序实例。

+0

完美地工作,谢谢! – Valyrion