2016-02-18 3 views
1

Я понимаю, как RAP создает области с определенным потоком для каждого клиента и так далее. Я также понимаю, как область применения уникальна среди нескольких клиентов, однако я не знаю, как получить доступ к этой конкретной области в одном потоке.Eclipse RAP Многоклиентский, но односерверный поток

Я хотел бы иметь серверную часть (с доступом к базам данных и прочее), которая представляет собой одно исполнение, чтобы обеспечить глобальное знание всей транзакции и что запросы от клиентов выполняются последовательно, а не параллельно.

В настоящее время я доступ к контексту приложения, как следует из интерфейса:

synchronized(MyServer.class) { 
    ApplicationContext appContext = RWT.getApplicationContext(); 

    MyServer myServer = (MyServer) appContext.getAttribute("myServer"); 
     if (myServer == null){ 
      myServer = new MyServer(); 
      appContext.setAttribute("myServer", myServer); 
     } 
    myServer.doSomething(RWTUtils.getSessionID()); 
} 

Даже если доступ MYSERVER объекта и запросов запуска, то выполнение будет по-прежнему работают в потоке пользовательского интерфейса.

А пока единственный способ обеспечить последовательность является использование синхронизируется следующим на моем сервере

public class MyServer { 
    String text = ""; 

    public void doSomething(String string) { 
     try { 
      synchronized (this) { 
       System.out.println("doSomething - start :" + string); 
       text += "[" + string + "]"; 
       System.out.println("text: " + (text)); 
       Thread.sleep(10000); 
       System.out.println("text: " + (text)); 
       System.out.println("doSomething - stop :" + string); 
      } 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

Есть ли лучший способ не должны управлять синхронизации потоков самостоятельно?

Любая помощь приветствуется

EDIT: Чтобы лучше объяснить себе, вот что я имею в виду. Либо я доверяю базе данных, чтобы обрабатывать несколько запросов должным образом, и я должен обрабатывать также некоторые другие знания синхронным образом для обмена информацией между клиентами (пример A), или я нахожу решение, в котором другой поток обрабатывает оба (пример B), знания и базы данных. Конечно, проблема здесь заключается в том, что один клиент может блокировать других, но это может управляться потоками фона для длительных действий, большинство из них не будут проблемой. Мой первоначальный вопрос состоял в том, может быть, уже есть какой-то конкретный поток области приложения, который делает пример B, или есть пример A на самом деле путь?

Eclipse RAP threads: how to handle shared knowledge and database access?

Заключение (до сих пор)

В принципе, вариант A) это путь. Для доступа к базе данных для этого требуется объединение пулов, и для общей информации потребуется тщательная синхронизация ключевых объектов. Основное внимание должно быть уделено проектированию базы данных и синхронизации объектов, чтобы два клиента не могли одновременно писать несовместимые данные (например, писать противоречащие записи, которые делают результат зависимым от порядка записи).

ответ

1

Прежде всего, способ, которым вы создаете MyServer в первом фрагменте, не является потокобезопасным. Вероятно, вы создадите более одного экземпляра MyServer.

Вам необходимо синхронизировать создание MyServer, как это, например:

synchronized(MyServer.class) { 
    MyServer myServer = (MyServer) appContext.getAttribute("myServer"); 
    if (myServer == null){ 
    myServer = new MyServer(); 
    appContext.setAttribute("myServer", myServer); 
    } 
} 

Смотрите также этот пост How to implement thread-safe lazy initialization? для других возможных решений.

Кроме того, ваш код вызывает doSomething() на клиентской нити (т.поток пользовательского интерфейса), что приведет к тому, что каждый клиент будет ждать обработки ожидающих запросов других клиентов. Пользовательский интерфейс клиента станет невосприимчивым.

Чтобы решить эту проблему, ваш код должен вызывать doSomething() (или любую другую затянувшуюся работу по этому вопросу) из фонового потока (также см Threads in RAP)

Когда фоновый поток завершится, вы должны использовать Server Push для обновления пользовательского интерфейса.

+0

Спасибо за ответ. Да, вы правы, мой звонок на myserver небезопасен, я просто написал это, чтобы проверить концепцию, это не обычный способ сделать это :) Во всяком случае, я вижу много примеров того, как вызывать поток пользовательского интерфейса из но я не знаю, как выполнить фоновое действие с пользовательского интерфейса. – Jarod

+0

PS: Отредактирован мой код выше, чтобы добавить безопасный доступ к потоку – Jarod

+0

См. Пример кода в главе Server Push, все там –

Смежные вопросы