Параллелизм Java: обеспечение безопасного доступа к веб-сервису - PullRequest
0 голосов
/ 03 августа 2009

Мне бы хотелось узнать правильный / лучший способ обработки параллелизма с помощью веб-службы Axis2.

Например, учитывая этот код:

public class MyServiceDelegate
{
    @Resource
    UserWebService service; // Injected by spring

    public CustomerDTO getCustomer()
    {
       String sessionString = getSessionStringFromCookies();
       service.setJSESSIONID(sessionString);
       CustomerDTO customer = service.getCustomerFromSessionID();
    }
}

Обратите внимание, что в приведенном выше UserWebService является сторонним API. Служба требует, чтобы при совершении звонков мы передавали куки с JSESSIONID аутентифицируемой сессии.

Правильно ли я считаю, что это утверждение не является потокобезопасным? IE., Учитывая два потока, возможно ли следующее?

  • Тема A: service.setJSESSIONID("threadA")
  • Тема B: service.setJSESSIONID("threadB")
  • Тема A: service.getCustomerFromSessionID // service.sesionID == "threadB"

Если так, каков наиболее подходящий способ справиться с этой ситуацией? Должен ли я использовать пул ресурсов для обслуживания? Или я должен объявить службу как синхронизированную?

    public CustomerDTO getCustomer()
    {
       synchronized( service ) {
          service.setJSESSIONID(sessionString);
          CustomerDTO customer = service.getCustomerFromSessionID();
       }
    }

Или есть другой, более подходящий способ решения этой проблемы?

Ответы [ 3 ]

3 голосов
/ 03 августа 2009

Будет ли каждый поток иметь свой собственный объект Delegate и, следовательно, свою собственную службу UserWebService?

В простом случае, если в стеке создаются делегаты, потоки будут независимыми.

Если стоимость создания высока, создайте пул объектов делегатов. Взятие одного из бассейна сравнительно дешево. Вы должны быть очень осторожны с ведением домашнего хозяйства, но фактически это то, что делается с соединениями с базой данных. В некоторых средах есть служебные классы для управления такими пулами, что, как правило, предпочтительнее, чем собственное.

0 голосов
/ 03 августа 2009

Как вы сказали, функция не является поточно-ориентированной. В Java есть простой способ создания мониторов, который является объектом, который позволяет только одному потоку одновременно получать доступ к функции. Больше информации о мониторах

Чтобы сделать его потокобезопасным, вы можете поставить синхронизированный, как вы сделали, вокруг выражения или перед именем функции:

public synchronized CustomerDTO getCustomer(){
    service.setJSESSIONID(sessionString);
    CustomerDTO customer = service.getCustomerFromSessionID();
}

Разница между ними заключается в том, какой объект вы превращаете в монитор.

0 голосов
/ 03 августа 2009

UserWebService - один из ваших классов? Если это так, я думаю, что я бы изменил подпись метода на:

public CustomerDTO getCustomer()
{
      CustomerDTO customer = service.getCustomerFromSessionID(sessionString);
}

И ваш UserWebService не должен поддерживать состояние, так что он по своей сути будет поточно-ориентированным

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...