2015-06-08 42 views
2

我仔細看過這些「可能已經有答案的問題」,並且很驚訝地發現我找不到我要求的東西......Java - 如何從Runnable之前獲取堆棧跟蹤?

當(例如)EDT中發生異常時,或者您只是想檢查堆棧,無論出於何種原因,只需將堆棧找回到Runnable的run()即可。但是,如何找到運行Runnable的線程(以及棧)呢?並尋找線程(和因此堆棧)運行線程的Runnable ...等等...等等...

我知道Thread.getAllStackTraces()...但如何可能一個確定哪些線程稱爲「當前線程」?除了「叫」不是正確的詞...我的意思是哪個當前線程。

+0

你的問題不是很具體,但通常是寫在stacktrqce。你的堆棧跟蹤是怎樣的? – Dici

+1

沒有煩人,我想知道你對Runnables有多少了解,例如Runnables使用EventQueue.invokeLater()運行。 Thread.currentThread.dumpStack()不會顯示比「run」更遠的堆棧... –

+0

'Runnable'只是一個接口,你可以以任何你想要的方式使用它...自從Java 8使用這個接口不時爲我的lambdas,這只是一個使用它的例子,而不調用'invokeLater'。你甚至不顯示任何代碼,所以沒有辦法給你一個很好的答案。你的問題是模糊的,不僅如此,你也缺乏謙卑 – Dici

回答

2

當你開始你的新線程時,原來的線程已經開始做其他的事情。在稍後的時間點獲取該線程正在做什麼的堆棧跟蹤可能是無關緊要的。你想要的是當線程啓動時捕獲堆棧。

您可以做的是創建一個例外,並在創建時傳遞給Runnable。異常將包含直到創建runnable時的堆棧。

事情是這樣的:

ExecutorService executor = Executors.newSingleThreadExecutor(); 

public void foo() { 
    final Exception starterStackTrace = new Exception(); 
    executor.execute(new Runnable() { 

     @Override 
     public void run() { 
      try { 
       // do stuff 
      } catch (Exception e) { 
       e.printStackTrace(); // Thread exception 
       starterStackTrace.printStackTrace(); // How thread was started 
      } 
     } 
    }); 
} 
+0

聽起來像對我來說是一個討厭的伎倆。 –

+0

「無關」...哇,這是一個相當的詞使用...如果我們試圖診斷髮生了什麼事情(例如不好的事情),那麼我們是否有合理的願望去了解特定的Runnable如何運行? –

+1

@mikerodent絕對!但是當線程啓動時,你對堆棧感興趣,而不是當你在線程中得到異常時的堆棧。因此,您需要這樣做以在創建線程時保存堆棧。 –

-1

我現在3個月前問這個問題,我花了整個夏天,除其他事項外,制定與此連接的工具,整個負載...專爲Jython的exception-處理。 Jythonistas會明白,在Jython中你可以做的事情是Java會大規模地掙扎。

除此之外,我設法使這些工具追蹤一系列Runnables(它們的堆棧記錄/凍結,以便將來列出,以便在將來運行新的Runnable時)直接回溯到應用程序的啓動線程。

我面臨的另一個挑戰是使所有這些工作不僅僅是直接運行應用程序,還要在使用Python unittest模塊進行單元測試時。 (據我所知)Jythonistas從來沒有在Jython上下文中提出過單元測試的問題,原因很簡單,如果你需要啓動一個新線程(通常是運行某些東西在美國東部時間),單元測試結束時的失敗結果可能無益於您。

任何有興趣在檢查出(也許提高)我的東西,歡迎下載......請給我發一個