Java并发性:使webservice访问线程安全

Java并发性:使webservice访问线程安全,java,web-services,thread-safety,Java,Web Services,Thread Safety,我想知道使用Axis2 Web服务处理并发性的正确/最佳方法 例如,给定此代码: public class MyServiceDelegate { @Resource UserWebService service; // Injected by spring public CustomerDTO getCustomer() { String sessionString = getSessionStringFromCookies();

我想知道使用Axis2 Web服务处理并发性的正确/最佳方法

例如,给定此代码:

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
的cookie

我假设此语句不是线程安全的,对吗?例如,给定两个线程,是否可能发生以下情况

  • ThreadA:
    service.setJSESSIONID(“ThreadA”)
  • ThreadB:
    service.setJSESSIONID(“ThreadB”)
  • ThreadA:
    service.getCustomerFromSessionID//service.sesionID==“threadB”
如果是这样,处理这种情况最合适的方法是什么?我应该使用资源池来提供服务吗?或者我应该将服务声明为已同步

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

或者,还有其他更合适的方法来处理此问题吗?

每个线程是否都有自己的委托对象,从而有自己的UserWebService服务

在简单的情况下,如果在堆栈上创建委托,则线程将是独立的


如果创建成本很高,请创建一个代理对象池。从泳池里拿一个比较便宜。您需要非常小心地进行内务管理,但实际上这是数据库连接的工作。有些环境具有用于管理此类池的实用程序类—往往比您自己的更可取。

每个线程是否都有自己的委托对象,从而有自己的UserWebService服务

在简单的情况下,如果在堆栈上创建委托,则线程将是独立的


如果创建成本很高,请创建一个代理对象池。从泳池里拿一个比较便宜。您需要非常小心地进行内务管理,但实际上这是数据库连接的工作。有些环境具有用于管理此类池的实用程序类—往往比您自己的更可取。

UserWebService是您的类之一吗?如果是这样,我想我应该将方法签名更改为:

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

如果没有UserWebService维护状态,那么它将本质上是线程安全的

UserWebService是您的类之一吗?如果是这样,我想我应该将方法签名更改为:

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

并且不让您的UserWebService保持状态,这样它将本质上是线程安全的

正如您所说,该函数不是线程安全的。Java有一种制作监视器的简单方法,它是一种一次只允许一个线程访问函数的对象。更多关于

要使其线程安全,您可以将synchronized放在表达式周围或函数名之前,就像您所做的那样:

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

两者的区别在于将哪个对象变成监视器。

正如您所说,该函数不是线程安全的。Java有一种制作监视器的简单方法,它是一种一次只允许一个线程访问函数的对象。更多关于

要使其线程安全,您可以将synchronized放在表达式周围或函数名之前,就像您所做的那样:

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

两者之间的区别在于将哪个对象变成监视器。

不幸的是,不是。服务要求在调用它之前,我们在服务上设置JSESSION ID,以便它可以识别我们正在使用的经过身份验证的会话。我推断会话ID是在委托对象上设置的,然后调用远程服务,会话id概念上在cookie中。在这种情况下,结束调用仍然会留下竞争的可能性。不幸的是,没有。服务要求在调用它之前,我们在服务上设置JSESSION ID,以便它可以识别我们正在使用的经过身份验证的会话。我推断会话ID是在委托对象上设置的,然后调用远程服务,会话id概念上在cookie中。在这种情况下,结束通话仍然有可能进行比赛。这是可能的,但似乎很昂贵。目前,委托被声明为Springbean,具有单例作用域。我们可以将其更改为使用原型,从而每次实例化委托和服务,但是,这似乎会带来很大的开销。有更好的方法吗?这是可能的,但似乎很昂贵。目前,委托被声明为Springbean,具有单例作用域。我们可以将其更改为使用原型,从而每次实例化委托和服务,但是,这似乎会带来很大的开销。有更好的方法吗?在这种情况下,有没有理由选择同步方法而不是委托池(反之亦然?)在web服务调用期间进行同步对我来说是个糟糕的主意。代理池是我的选择。在这种情况下,是否有理由选择同步方法而不是代理池(反之亦然?)在web服务调用期间进行同步对我来说是个糟糕的主意。代表池是我的选择。