2013-07-22 18 views
1

我有一個java服務器應用程序通過套接字與客戶端進行通信。每個客戶端請求都在一個新線程中處理。但對於一些請求,我需要同步兩個客戶端。阻塞線程,直到它從某個其他線程(java)獲得特定信號

實施例:

  • 客戶端A發送到在S服務器S.
  • 線程S1的請求接受通知S1客戶端B瞭解這個請求(經由Google雲端通訊)A.
  • 的請求。
  • S1應該阻止NOW
  • 客戶端B從S收到的信息和發送到S的請求
  • 在S
  • 線程S2接受
  • S1現在應該釋放,並且從得到的消息B的請求S2
  • S1傳送答案給客戶A

我知道的鎖定狀態的機制,但是,這並不在這裏工作,因爲在創建線程時,我不知道的情況。我需要這樣的東西:

// Pseudo Code 
// on the S1 Thread, first argument beeing a signal ID, second a timeout 
s1.waitForSignal("clientB", 10000); 
// and on the S2 Thread to continue S1 
SignalSender.send("clientB"); 

在Java中有這樣的可能嗎?有沒有其他解決方案來解決我的問題?

+0

是的,有等待和通知方法。嘗試使用它們。 – Ankit

+3

不,*不要使用wait和notify *。它們是過去的遺蹟,新代碼不應該使用它。從'java.util.concurrent'使用適當的同步輔助,例如'CountDownLatch'。 –

+0

謝謝,我喜歡披薩的例子。但等待和通知我仍然需要兩個線程中的等待對象的實例,不是嗎?因爲我不知道哪個線程必須等待或通知創建哪個線程。我從套接字解析消息時(或者在獲取SSLSession對象時)首先知道這一點。 – user2564801

回答

0

你的問題似乎是你沒有共享的引用,你可以調用wait/notify(更不用提你可以使用的共享鎖定條件了)。

那麼,首先在這兩個線程之間已經有東西已經共享:即,在你的情況下,字符串"ClientB"。如果你有這個,你需要做的就是將這個字符串映射到一個可以被這兩個類訪問的地方的單個引用。

最簡單的實現將是某處舉行靜態地圖領域,只是監控對象以某種方式填充:當然

public final class Monitors { 

    private Monitors() {} 

    private static final Map<String, Object> monitors = new HashMap<String, Object>(); 

    static { monitors.put("ClientB", new Object()); } 

    public static Object get(String key) { return monitors.get(key); } 

} 

,你可能需要編寫管理此映射,也許使用適當的服務內部鎖定和條件。另外,一個好主意是將等待和信令功能封裝在服務本身中,然後使用它:monitorService.waitForSignalsFrom("ClientB")

+0

所以你的回答真的是一個你認爲OP不應該做什麼的聲明? :) –

+0

不是真的:我指出了一個解決方案;實際的實施過於簡單,以至於無法使用。但是你是對的,那種警告最終會導致混亂:我會編輯:) –

+0

我只是給你一個難過的時間。它似乎並沒有一個非常乾淨的解決方案來解決這個問題(可以在SO回答中找到答案)。 –

相關問題