2014-02-27 20 views
0

如果我知道我希望通知的線索的ID,並且不分享其他常見資源,我可以通知它嗎? 這兩個線程都由同一個應用程序啓動。不共享公共資源的線程可能基於線程ID /名稱進行通知嗎?

另一個線程通過使用Thread.currentThread()等待(500);

+0

你不''通知'一個線程 - 你通知服務員對象。然而,你可以「中斷」一個特定的線程。 – davmac

回答

1

是的 - 但您必須停止使用wait

該技術是爲每個正在運行的線程維護一個包含隊列的Map<String,BlockingQueue>String鍵是線程ID。

當您希望線程暫停時,請使用queue.poll(long, TimeUnit)而不是wait。你只需要在隊列中放一些東西來喚醒線程,顯然如果你知道線程的ID,你可以很容易地從Map獲得它的Queue

+0

在等待/通知任何常規對象時使用阻塞隊列有什麼好處嗎? – Sam

+0

@Sam - 是的!它更加靈活,能夠正確處理Wait/Notify系統中固有的所有邊緣條件。在我看來,沒有什麼可以使用Wait/Notify來完成對新的java.util.concurrent對象之一的處理。 – OldCurmudgeon

+0

我喜歡這個答案,但我想區分它從另一個線程接收信號(作爲隊列的添加)以及輪詢時間並相應地執行不同代碼的情況,我無法做到這一點,你能提出什麼建議嗎? This http://stackoverflow.com/questions/22063249/how-to-make-a-thread-wait-for-a-notify-for-a-specific-time-and-execute-code-acco/22079635 ?noredirect = 1#22079635是我真正的問題..! – Sam

0

只要它是在同一個線程組,可以通過所有的線程使用Thread.enumerate()迭代,並找到指定線程通過它的id和做平常同步和.notify()。

This提供了迭代所有線程的其他方法。

0

您只想通知等待同一鎖的線程。不要使用當前的線程對象作爲鎖,它沒有幫助。一旦線程被喚醒,你需要檢查一個條件來防止虛假的喚醒。如果您確定只有一個線程正在等待鎖,那麼調用鎖對象上的notify應喚醒等待的線程。

+0

鑑於涉及的兩個線程都是在代碼的真正不同的部分中啓動的,因此它們中的任何一個都不會彼此鏈接太多,這是否意味着,我將不得不轉到主起始文件,並將對象傳遞給這些線程? – Sam

+0

我想你想讓一個線程通知其他線程,因爲一個線程的動作取決於另一個線程的先前動作。您需要爲線程間通信設置一個通用鎖。如果兩個線程根本不相關,那麼爲什麼不需要它們之間的任何協調。 –

+0

其實我的問題是鏈接到這個http://stackoverflow.com/questions/22063249/how-to-make-a-thread-wait-for-a-notify-for-a-specific-time-and-execute- code-acco?noredirect = 1#comment33456544_22063249 這裏的一個線程只是一個監聽線程,它應該在其他線程通知它是否收到特定類型的數據包......到目前爲止,我想我將不得不使用一個共同的資源。 – Sam

0

您可以爲線程提供一些通信對象,因此您不必依賴線程名稱。

例子:

class Notifier extends Thread { 
    private final Object common; 

    Notifier(Object common) { this.common = common; } 

    public void run() { 
     // do work 
     synchronized (common) { common.notify(); } 
    } 
} 

class Waiter extends Thread { 
    private final Object common; 

    Waiter(Object common) { this.common = common; } 

    public void run() { 
     // do work 
     synchronized (common) { common.wait(TIMEOUT); } 
    } 
} 

一個更好的辦法是使用java.util.concurrent.CountDownLatch達到相同的效果。

0

是的,這是可能的。但它很醜並且可能脆弱和/或效率低下。

由於@nos說,你可以使用Thread.enumerate()枚舉你ThreadGroupThread對象,測試每一個,直到你可以找到與預期的名稱和/或線程ID線程。如果組中有很多線程,那顯然是低效的。

脆弱出現在以下幾個方面:

  • 與給定名稱或ID的線程可能不再存在。
  • 可能有多個具有相同名稱的線程。
  • 線程ID值最終將在足夠的線程已經消失時被回收。

,並在同步方面,

  • 有可以想象是同步使用等待/通知對Thread對象的應用程序(或庫代碼)等部位,你可以得到不想要的通知作爲結果。
  • 在某些Java平臺上(至少在歷史上)有可能獲得自發通知...因此,使用wait/notify而不測試共享條件變量可能會導致錯誤的同步。

IMO,你最好創建(私人)對象,你可以等待/通知,並使用適當的條件變量。或者它不具有吸引力,請使用現有的更高級別的併發類之一進行同步。