如何防止 vaadin 应用程序实例相互干扰?

发布于 2024-12-16 13:38:28 字数 747 浏览 0 评论 0原文

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

我尝试将 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();
}

我选择了一个单例对象,因此我始终可以访问应用程序实例中各处的缓存数据和用户的肥皂连接,而我能想到的唯一其他方法就是在某处拥有一个静态对象,但是静态对象关键字似乎首先是我所有问题的原因。有什么办法可以解决这个问题还是有其他原因造成的?

I've got a Vaadin application and I'm getting some strange behaviour when running two instances of the application at the same time (one in FF, another in IE). I've already removed most static objects (these caused the application to completely reload when used parallel to another open application) and now I can interact normally with the UI without the complete reset. However, I'm now noticing that I'm getting only one user's data in both interfaces. I assume this is caused by singleton objects I'm using to manage some data caching and a SOAP connection. I'd like to know if it's the singleton pattern itself that's causing the strange output or is it just the static instance object I'm keeping?

I've tried using ThreadLocal with my singleton, but all my variables are always null when I try to use them in my singleton's functions. Currently my singleton contains this, which is probably terribly, terribly wrong since it doesn't work.

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

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

I chose a singleton object so I'd always have access to the cached data and my user's soap connection everywhere in my application instance, and the only other way I can think of for doing that is to have a static object somewhere, but the static keyword seems to be the cause of all my problems in the first place. Is there any way around this or is there something else causing it?

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

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

发布评论

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

评论(1

半步萧音过轻尘 2024-12-23 13:38:28

本地实例化线程的更好方法是这样

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

但是,这里的问题是 Web 应用程序服务器“池”并重用线程。用 Vaadin 术语来说,并非应用程序的每个请求都在同一个线程中处理 - 即线程 1 可以处理应用程序实例 1 和应用程序实例 2 的请求。如果您的 SoapClient 缓存了适合应用程序实例 1 的信息,则应用程序 2 的 UI 最终可能会使用应用程序的 SoapClient 1。

假设(根据您的描述)“应用程序特定”信息缓存在 SoapClient 中,我建议您

  • 像平常一样在应用程序对象上创建并存储 SoapClient字段(非静态,非线程本地)

  • 如果您需要访问应用程序(为了获取 SoapClient) ,并且从您所在的位置来看,使用 ThreadLocal 访问模式 会很棘手。请参阅链接上的第二个示例。请注意,ThreadLocal 在 HttpRequest 的开头设置,并在末尾“取消设置”,确保同一线程上的任何后续请求不会获取相同的应用程序实例。

A better way to instantiate your thread local would be this

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

However, your problem here is web app servers "pool" and re-use threads. In Vaadin terms,not every request for an application is processed same thread - i.e. Thread1 could process requests for both App instance 1 and App Instance 2. If your SoapClient caches information appropriate to App instance 1, the UI for App 2 could end up using the SoapClient for App 1.

Assuming (from your description) that "app specific" information is cached in the SoapClient, I would suggest that you

  • Create and store the SoapClient on your Application object as a normal field (not static, not threadlocal)

  • If you need to access the application (in order to get the SoapClient), and it's tricky from where you are, use the ThreadLocal access pattern. See the second example on the link. Note that the ThreadLocal is set at the beginning of the HttpRequest, and "unset" at the end, ensuring that any subsequent requests on the same thread do NOT get the same application instance.

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