2012-07-14 155 views
1

某些前提在我原來的問題上發生了變化inter-thread communication between java application and jax-ws web service(我也在簡化問題以使它更容易理解(並因此得到回答)......希望沒關係版主。)java web應用程序和web服務之間的線程間通信

Web服務線程(THREAD-1)在套接字上放置請求並進入休眠狀態等待響應。另一個偵聽器線程(THREAD-2)(作爲單獨的Web應用程序運行,一旦收到響應)必須將THREAD-1喚醒。

我該如何做(推送通知方式)?

他們都有權訪問數據庫表。 THREAD-1可以在睡覺之前將其唯一的ID放在表格中。 THREAD-2一旦收到響應並確定它屬於THREAD-1,就會更新數據庫表中相應的行。現在,THREAD-1可以在數據庫表上進行輪詢(定期)以檢查響應是否已到達。

但我期待以推送通知的方式做到這一點。應答到達時應立即通知THREAD-1,而不必每隔幾秒輪詢一次。

+1

第一反應,而閱讀此:*不這樣做*。第二:*不要自己動手*。這是消息排隊。所以找到一個解決方案/產品/框架,可以讓您在數據庫之上處理消息排隊。 – Arne 2012-07-14 17:50:27

+0

我認爲消息隊列更適合異步通信,在我的情況下,THREAD-1無法將請求放入隊列並忘記它 - 它實際上必須等待阻塞模式以獲取其響應以更新其調用客戶端(web服務客戶在這種情況下)關於收到的響應。這是我爲什麼不應該在這種情況下使用消息隊列的第一個推理。 – 2012-07-14 18:23:49

回答

2

那麼,正如評論所示:最好不要嘗試自己實現這一點。但是,基本上,您可以使用標準Java線程同步wait()/ notify()

  • 線程1套遠程調用與線程2連同唯一的呼叫ID。
  • 線程1現在wait()確實同步對象(而不是sleep()
  • 線程2做的工作,並返回它調用在JVM中一些遠程回調方法線程1駐留在結果上 - 呼叫ID與結果一起傳遞
  • Thread-1端的回調方法使結果通過呼叫ID可用,並通過notifyAll()
  • 喚醒所有等待的線程。線程1檢查他們的結果是否到達,如果是,他們繼續工作,如果沒有wait()再次。爲線程1側

僞代碼:

HashMap<String, Object> results; 

// Called by Thread-1 to access Thread-2 
public void doIt() { 
    String callId = "aUniqueCallId"; 
    Object result = null; 
    remoteCallToThread2(callId); 
    synchronized(results) { 
     while((result = results.remove(callId)) == null) { 
      results.wait(); 
     } 
    } 
    doSomethingWith(result); 
} 

// Called remotely by Thread-2 when result is available 
public void callback(String callId, Object result) {  
    synchronized(results) { 
     results.put(callId, result); 
     results.notifyAll(); 
    } 
} 

當然這只是一個基本的想法,不能被用作這樣的,有很多的東西在這裏考慮。

+0

感謝您的詳細回覆@lost。但是,如果你能評論我的理由,不希望使用基於消息隊列的解決方案,我將不勝感激。 **當THREAD-1(來自web CLiENT-1的web服務調用的一個實例)發送請求(通過套接字)時,它必須在發送請求後立即釋放該套接字。 還有另一個監聽器線程持續監聽該套接字的響應,但這些響應可能會失序,因此此監聽器線程必須查看每個響應並通知相應的等待線程其響應已到達。 – 2012-07-14 18:54:51

+0

如果有人(包括@Arne)能夠解釋如何通過消息隊列來實現這個功能,那將是非常好的選擇。我當然更喜歡那條路線,因爲我不必處理那些細節中的線程。 – 2012-07-14 18:55:36

+0

我的回答與Thread-2的回調無關。它可以通過直接來自Thread-2的WS調用來完成,它也可以通過MQ系統上的消息進入。如果你不想讓線程1阻塞,那麼wait()/ notify()是要走的路。當你剛剛從Thread-1到Thread-2(不知道這些框架的細節)發起同步WS調用時,我提出的建議已經包含在常見的WS框架中。如果是這種情況,這將是最簡單的解決方案。你必須檢查你的框架的屬性。 – lost 2012-07-14 19:42:33

3

如果您的後端請求很快完成,並且您不會有客戶端請求處理的洪流,您可以讓Web服務通過剛纔打開的同一個套接字等待響應。它可以阻止等待讀取響應。但是,如果您有權訪問Servlet 3.0(例如Tomcat 7),則可以使用asynchronous HTTP requests。它允許您將處理Web服務客戶端的線程釋放回池中,而無需響應客戶端的請求。當響應消息從後端服務到達時,從servlet容器中抓取相應的Web服務客戶端請求,並將最終響應發送回Web服務客戶端。

+0

這將是eas即將實施,並且我將在明天與傳統平臺團隊*(我們在此案例中向傳統平臺打開套接字)確認此設計。他們昨天告訴我THREAD-1發送一個請求到套接字並釋放套接字上的句柄。由於這種Web服務將被多個Web客戶端(多個用戶在互聯網上訪問Web服務)調用,所以它們都可以並行地提出請求,並且響應可以在他們執行時返回。如果我們按照你的建議,吞吐量將大幅下降 – 2012-07-14 19:44:07

+0

我的印象是這些後端請求很快就完成了。因此,請參閱我的編輯。 – 2012-07-14 20:03:01

+0

thx您的建議@David Harkness - 這就像一個混合的解決方案,似乎並不需要與線程等待/通知模式工作,並自動照顧匹配響應與他們相應的請求線程..(一廂情願的想法 - 我會在閱讀該鏈接後確認這一點,現在就快速查找,看起來_PROMISING_).. – 2012-07-14 21:11:27

相關問題