Java并发:使Web服务访问线程安全

时间:2009-08-03 09:13:44

标签: java web-services thread-safety

我想知道使用Axis2 webservice处理并发的正确/最佳方法。

例如,鉴于此代码:

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。

我认为这句话不是线程安全的吗? IE。,给定两个线程,是否可能发生以下情况?

  • 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();
       }
    }

或者,是否有另一种更合适的方法来处理这个问题?

3 个答案:

答案 0 :(得分:3)

每个线程是否都有自己的Delegate对象,因此它自己的UserWebService服务?

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

如果创建成本很高,请拥有一个委托对象池。从游泳池中取一个便宜得多。你需要非常小心管理,但实际上这是用数据库连接完成的。某些环境具有用于管理此类池的实用程序类 - 往往比滚动自己更好。

答案 1 :(得分:0)

UserWebService是你的一个类吗?如果是这样,我想我会将方法签名更改为:

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

并没有你的UserWebService维护状态,这样它本身就是线程安全的

答案 2 :(得分:0)

正如您所说,该功能不是线程安全的。 Java有一种简单的方法来生成监视器,这是一个只允许一个线程一次访问一个函数的对象。有关monitors

的更多信息

为了使线程安全,您可以像在表达式周围或函数名称之前那样同步:

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

两者之间的差异是你变成监视器的对象。