Как не допустить, чтобы экземпляры приложений vaadin мешали друг другу? - PullRequest
0 голосов
/ 15 ноября 2011

У меня есть приложение Vaadin, и я получаю странное поведение при запуске двух экземпляров приложения одновременно (один в FF, другой в IE). Я уже удалил большинство статических объектов (это привело к полной перезагрузке приложения при использовании параллельно с другим открытым приложением), и теперь я могу нормально взаимодействовать с пользовательским интерфейсом без полного сброса. Однако сейчас я замечаю, что в обоих интерфейсах я получаю данные только одного пользователя. Я предполагаю, что это вызвано одноэлементными объектами, которые я использую для управления некоторым кэшированием данных и соединением 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();
}

Я выбрал одноэлементный объект, чтобы у меня всегда был доступ к кэшированным данным и соединению мыла моего пользователя везде в экземпляре моего приложения, и единственный другой способ, который я могу придумать для этого, - это где-то иметь статический объект, но ключевое слово static кажется причиной всех моих проблем. Есть ли способ обойти это или что-то еще вызывает это?

1 Ответ

5 голосов
/ 15 ноября 2011

Лучший способ создать локальный поток - это

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

Однако, ваша проблема здесь в том, что серверы веб-приложений "пул" и повторно используют потоки. С точки зрения Vaadin, не каждый запрос на приложение обрабатывается одним и тем же потоком - т. Е. Thread1 может обрабатывать запросы как для экземпляра приложения 1, так и для экземпляра приложения 2. Если ваш SoapClient кэширует информацию, соответствующую экземпляру приложения 1, пользовательский интерфейс приложения 2 может в конечном итоге использовать SoapClient для приложения 1.

Предполагая (из вашего описания), что "специфичная для приложения" информация кэшируется в SoapClient, я бы предложил вам

  • Создайте и сохраните SoapClient на объекте Application как обычное поле (не статическое, не локальное)

  • Если вам нужно получить доступ к приложению (чтобы получить SoapClient), и это сложно, где вы находитесь, используйте Шаблон доступа ThreadLocal . Смотрите второй пример по ссылке. Обратите внимание, что ThreadLocal устанавливается в начале HttpRequest и «отменяется» в конце, гарантируя, что любые последующие запросы в том же потоке НЕ получат один и тот же экземпляр приложения.

...