2009-08-03 68 views
0

我想知道處理Axis2 web服務併發的正確/最好的方法。Java併發:使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。

我正確的假設這條語句不是線程安全的嗎? 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

每個線程都有自己的委託對象,因此它自己的UserWebService服務?

在簡單的情況下,如果在堆棧上創建委託,則線程將是獨立的。

如果創建成本很高,請創建一個委託對象池。從池中取出一個便宜。你需要非常小心的管家,但實際上這是數據庫連接所做的。一些環境擁有用於管理這種池的實用程序類 - 往往比滾動自己的更合適。

+0

這是可能的,但看起來很昂貴。目前該委託被聲明爲一個spring bean,具有單例作用域。我們可以將其改爲使用原型,從而每次實例化委託和服務,但是,這似乎是一個很大的開銷。有沒有更好的辦法? – 2009-08-03 09:26:19

+0

編輯添加替代設計 – djna 2009-08-03 09:32:07

0

UserWebService是你的一個類嗎?如果是這樣,我想我會的方法簽名更改爲:

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

,而不是有你的UserWebService保持狀態,這樣會本質上是線程安全的

+0

不幸的是,沒有。該服務要求在對它進行調用之前,我們在服務上設置JSESSION ID,以便它可以識別我們正在使用的經過驗證的會話。 – 2009-08-03 09:25:01

0

正如你所說的,功能不線程安全。 Java有一個簡單的方法來創建監視器,這是一個只允許一個線程一次訪問函數的對象。在monitors

更多信息以使它線程安全的,你可以把已同步,像你一樣,周圍的表達,或函數名前:

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

兩者之間的區別是哪個對象轉成監視器。