2013-02-08 76 views
7

我需要能夠爲當前正在運行的線程注入一些退出代碼。我一直在努力與這一個了一段時間,我終於想出了一個解決方案在這裏是一些代碼類似於我在做什麼:線程退出回調

public static void injectThreadExitCallback(final Runnable callback) { 
    final curr = Thread.currentThread(); 
    new Thread() { 
     @Override 
     public void run() { 
      try { 
       curr.join(); 
       callback.run(); 
      } catch (InterruptedException ex) { 
       ... logging ... 
      } 
     } 
    }.start(); 
} 

這似乎很好地工作和做我想要什麼,我唯一擔心的是,如果這導致任何泄漏或其他不良副作用,我可能不會看到。

或者這是非常好的,如果是這樣,這是非常有用的。我可以看到一個簡單的庫,可以動態地將退出代碼添加到現有的線程。

+1

看起來不錯;請注意,回調將在單獨的線程上運行。 – 2013-02-08 20:15:40

+1

將回調移動到'finally'塊意味着如果'join'在目標線程退出之前拋出一個將會發生的異常,它就會運行。此外,除非某個外部代理開始中斷所有線程,否則連接永遠不會拋出異常。 – 2013-02-08 20:44:55

+0

如果您在此方法內創建的匿名線程中斷,那麼回調是否應該被調用是非常值得懷疑的。中斷一個線程的目的是停止它正在做的事情。由於這個線程唯一做的就是等待調用回調函數,所以中斷它的唯一原因就是阻止回調函數的運行。 – 2013-02-08 20:53:58

回答

3

您做的更好

new Thread() { 
    @Override 
    public void run() { 
     try 
     { 
      // Thread logic here 
     } 
     finally 
     { 
      // Thread exit logic here 
     } 
    } 
}.start(); 
+1

好點!這樣,如果我包裹的線程死亡仍然會做我需要做的事情。 – 2013-02-08 20:14:03

+0

這不完全是注射,是嗎?線程代碼需要修改以合併線程退出邏輯。 (或者你是在談論重組OP的建議行爲注入線程? – 2013-02-08 20:17:07

+0

我認爲他說我需要移動我的回調,以防例外情況,我想。 – 2013-02-08 20:19:09

0

您可以catch塊之後或在final塊移動callback.run();如果你想確保它反正叫

+0

一般來說,中斷一個線程的唯一理由是讓它停止正在做的事情。在這種情況下,它所做的唯一事情就是等待調用回調。因此,你確定不希望在線程中斷時確保回調被調用! – 2013-02-08 21:35:56

+0

這是真的,但它取決於您希望確保調用'callback'或否的應用程序邏輯天氣。例如,如果'callback'正在執行一些清理任務,即使線程中斷,您也有合理的理由確保它被調用。 – iTech 2013-02-08 21:40:00

2

你不可能代碼注入到一個除非該線程正在積極協作,例如AWT中的Event Dispatch Thread,它的根部有一個將Runnable從隊列中取出並執行的循環。

您的設計可能會將數據競爭引入之前爲單線程且因此沒有併發問題的代碼。最後,設計浪費了一個寶貴的系統資源(一個線程),除了等待另一個線程完成之外什麼也不做。

如果您需要從外部修補一些現有的代碼,那麼它可能是唯一的選擇;如果沒有,最好爲它提供一個更有效的明確機制。