2010-01-28 77 views
0

我有一個java程序,具有多線程。我的問題是,我有時會超時。 因爲我有一些unix的東西,我看不到超時或/和鎖定在哪裏。問題在於,這不會每天晚上發生,只是不時發生。 實際上,一個unix組件(lsf)會終止線程(如果超過15分鐘)。因爲我看不出問題在哪裏,所以我想知道是否有人有任何想法。 有沒有機會啓動另一個java的東西,當我有一個鎖,寫一個日誌文件?如果,是的,會是什麼?Java多線程 - 檢測自動鎖定線程

+1

正如有人曾經寫的,多線程編程是95%思維和5%編寫代碼。所以更好的重新思考所有可能的種族和死鎖情況。 – Bozho 2010-01-28 15:24:09

+0

這是一個現有的非常大的應用程序。不可能考慮所有情況。我到達時已經準備好了。 – 2010-01-28 15:33:16

回答

3

jstack是一個命令行程序,您可以用它來反省正在運行的java程序。它會打印出每個線程的堆棧跟蹤,告訴你它是否被鎖定,甚至檢測到死鎖。這可以幫助您以交互方式調試問題。

如果你想在你的程序中獲得這些數據,你可以撥打Thread.getAllStackTraces()這將得到你所有的線程和他們的堆棧跟蹤列表,所以你可以看到線程在哪裏和他們的狀態,如果你想'做如果某個線程被鎖定,就像寫入日誌文件一樣。

+0

問題是我沒有經常遇到這個問題。 所以,我正在考慮類似於每次有鎖時寫入一些日誌的代碼片段和方法名稱。 這樣,在早上我可以分析日誌,看看是否有鎖,如果是的話,它在哪裏。 但我不知道該怎麼做。 – 2010-01-28 15:28:35

+0

這就是JCarder所做的(請參閱我的主要回復) – Rich 2010-01-28 15:31:03

+0

+1感謝提及Thread.getAllStackTraces() – stacker 2010-01-28 16:18:09

4

如果您必須讓應用程序繼續運行並且在錯誤的時間處於死鎖狀態,那麼您可能從JCarder(它是您告訴Java使用的代理程序)中獲得一些好處。程序運行完畢後,它會輸出各種診斷文件,然後可以將其轉換爲圖形以顯示死鎖。

另外,通過諸如Findbugs之類的東西運行你的代碼,這可能會指出一個微妙的死鎖情況,否則你沒有注意到。

+0

如果應用程序。肯定會造成死鎖,不太可能幹淨地終止。在能夠產生診斷之前,JCarder是否依靠徹底的終止? – Adamski 2010-01-28 15:41:37

+0

這是一個代理,所以它傾向於能夠處理大多數正常終止。 OP的問題可能在於機器如何選擇殺死這個過程 - 如果它不是'JCarder友好'的方式,那麼它可能是沒用的。 – Rich 2010-01-28 15:45:38

+0

+1很酷的工具,希望我永遠不需要它 – stacker 2010-01-28 16:20:44

1

除了jstack你可以檢查出JConsole,這是一個GUI應用程序,允許您檢測死鎖,監視線程/內存/ CPU使用率,等它附帶的JDK。

JConsole在內部使用ThreadMXBean,您還可以使用它編程檢測死鎖;例如我通常安排在我的服務器應用程序以定期調用下面的代碼守護線程:

private void detectDeadlocks() { 
    logger.info("Checking for deadlocks."); 
    ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); 

    long[] threadIds = threadMXBean.findDeadlockedThreads(); 

    if (threadIds == null || threadIds.length == 0) { 
     logger.info("No deadlocks found."); 
    } else { 
     StringBuilder sb = new StringBuilder(); 

     for (long threadId : threadIds) { 
      ThreadInfo threadInfo = threadMXBean.getThreadInfo(threadId); 

      if (sb.length() > 0) { 
       sb.append(", "); 
      } 

      sb.append(threadInfo.getThreadName()).append(" (ID: ").append(threadId).append(')'); 
     } 

     logger.severe("Blocked Threads: " + sb); 
     // Raise alert here, etc. 
    } 
}