簡體   English   中英

如何找出誰在java中創建一個線程?

[英]how to find out who create a thread in java?

在tomcat中,如果webapp確實停止了一個無守護程序線程,則tomcat無法通過shutdown.sh關閉

例如:

public class demo implements ServletContextListener{

  public void contextDestroyed(ServletContextEvent arg0) {
    // TODO Auto-generated method stub
    // yes,we can cancel timer in here,but this is not the major problem
   }

  public void contextInitialized(ServletContextEvent arg0) {        
    Timer timer = new Timer();
    timer.schedule(new Test(), 1000, 1000*10);
    }
}

public class Test extends TimerTask{  
@Override
public void run() {
    System.out.println("AAAA");        
   }
}

如上所述,tomcat無法通過shutdown.sh關閉。 來自jvisualvm的線程檢查員說:

"Timer-0" - Thread t@40
   java.lang.Thread.State: TIMED_WAITING
    at java.lang.Object.wait(Native Method)
    - waiting on <3957edeb> (a java.util.TaskQueue)
    at java.util.TimerThread.mainLoop(Timer.java:552)
    at java.util.TimerThread.run(Timer.java:505)

   Locked ownable synchronizers:
    - None

堆棧信息沒有指出哪個java類創建了線程,我的問題是如何找出誰從許多webapps創建線程。

謝謝!

以下是從最快/最可靠到最慢/最難的方法列表:

  1. 如果您擁有該類的源代碼,請在構造函數中創建一個異常(不實際拋出它)。 當您需要知道創建線程的時間時,您可以簡單地檢查或打印它。

  2. 如果您沒有源,則線程名稱可以是創建它的好提示。

  3. 如果名稱提示通用服務(如java.util.Timer ),則可以在構造函數中的IDE中創建條件斷點。 條件應該是線程名稱; 當有人創建具有此名稱的線程時,調試器將停止。

  4. 如果沒有太多線程,請在Thread的構造函數中設置斷點。

  5. 如果您有許多線程,請將調試器附加到應用程序並凍結它。 然后檢查堆棧跟蹤。

  6. 如果其他一切都失敗了,請獲取Java運行時源代碼並在要觀察的類中添加日志代碼,編譯新的rt.jar並用您的版本替換原始的。 請不要在生產中嘗試這種方法。

  7. 如果資金不是問題,您可以使用動態跟蹤工具,如Compuware APM,或者,如果您使用的是Linux或Solaris,則可以分別嘗試使用SystemTap和dtrace。

如果您可以控制該類,則可以在創建時捕獲堆棧跟蹤:

public class Test extends TimerTask {
  final StackTraceElement[] callerStack;

  public Test () {
    callerStack = Thread.currentThread().getStackTrace();
  }

  @Override
  public void run() {
    System.out.println("AAAA");
    System.out.println("Creator: "+Arrays.asList(callerStack));
  }

  @Override
  public String toString () {
    return "Test created by "+Arrays.asList(callerStack);
  }
}

您還可以編寫一個小的java Instrumentation代理來包裝線程構造函數(以及堆棧轉儲),而不是嘗試修改rt.jar類。

如果你有像Eclipse或Intellij這樣的IDE,你可以在各種Thread構造函數中設置斷點。 您可以使用調試器遠程連接到進程。 調試器將在構造線程時停止進程。 您可以觀察線程名稱之類的內容。 如果要匹配特定的線程名稱,也可以使用帶條件的斷點。

設定斷點。 https://www.ibm.com/developerworks/library/os-ecbug/

遠程調試https://dzone.com/articles/a-practical-guide-to-java-remote-debugging-in-the

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM