0

我查看了有关获取线程 ID 的现有问题,例如java-thread-id-and-stack-trace

但我无法弄清楚一些看似简单的事情。我想制作一个 JSP 工具来停止 Java 中的线程。

我知道这通常是个坏主意,但我们需要它,因为我们不能在我们的环境中使用 JConsole 会导致 JBoss 的一些硬化。

我的问题是,取一个 jstack 输出示例:

  1. Event Batch Processing (Spring UAA/1.0.2)" daemon prio=10 tid=0x0000000041e27800 nid=0x363b waiting on condition [0x00007f9a89267000] 从此哪个 id 将是thread.getId()定义的java.lang.Thread?这一行的最后一个标记是什么[0x00007f9a89267000]
  2. 如何将(Java 代码将是超级)hex转换为 Java long
  3. 你能告诉我为什么这不起作用 -> 我tid=从一个挂在一个永无止境的循环中的线程的 jstack 中获取了一个十六进制。然后我这样做了:

    Thread thrd = null;
    String thrdId =request.getParameter("thrd");
    if(thrdId != null){
        out.print("thread " + thrdId + " :");
        out.flush();
        Map<Thread,StackTraceElement[]> map = Thread.getAllStackTraces();
        Set tt = map.keySet();
        Iterator<Thread> ti = tt.iterator();
        try{
            long idFind = Long.parseLong(thrdId);
            out.print("<br> idFind thread |" + idFind + "| <br>");
            boolean found = false;
            while(ti.hasNext() ){
                thrd = ti.next();
                if(thrd.getId() == idFind){
                    out.print("<br> stopping thread " + thrd + " <br>");
                    out.flush();
                    thrd.stop();
                    out.print("<br>stopped " );
                    found = true;
                    break;
                }
            }
            if(!found){
                out.print("<br>not found " );
    
            }
        }catch(Exception e){
            out.println("<br>err " + e + "<br>");
        }
    
    }
    

未找到此输出。输入参数是 tid - 粘贴在 Windows 7 calc, Programmer mode (hex) 中,然后单击 Dec.

更新:

在我的测试代码中,当我制作了一个无限循环的 JSP,每隔几 10000 次迭代输出一个字符 - 然后做了一个 jstack,得到:

"http-0.0.0.0-8181-4" daemon prio=6 tid=0x000000000d4eb000 nid=0x2f58 waiting on condition [0x0000000010fee000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

...(stack trace)
at org.apache.jsp.t.testing.loop_jsp._jspService(loop_jsp.java
...more stack trace...

我运行 jstack 几次,每次都得到这个条目。

但是当我用 thread 运行我的 JSP 时id = 000000000d4eb000,它找不到它,因为应用程序容器唯一地命名了线程,我能够找到线程并且当我打印时:

out.print("" + cnt + " \"" + thrd.getName() + "\"| id :" + thrd.getId() + "| hex :" +  Long.toHexString(thrd.getId()) + "| <br>");

我得到:

93 "http-0.0.0.0-8181-4"| id :1389| hex :56d| 

93 is the thread number in my internal counter in the loop.

那么 jstack 显然将其识别为0x000000000d4eb000内部 JVM 所知道的 发现1389 hex :56d?最后将 JSP 改为按名称搜索并停止线程。幸运的是线程名称都不同。但这是一个错误 - 运行 Windows、JBoss 4.2、Java 1.6 更新 32?

4

1 回答 1

1

您只能找到并停止您自己的线程。我会尝试中断线程,以防它可以优雅地停止。

停止线程通常是个坏主意,因为它会使应用程序处于不一致或不可恢复的状态。避免这种情况的唯一方法是对线程可能正在做的所有事情有一个很好的了解,在这种情况下,修复代码使其优雅停止可能更简单更好

我们不能在我们的环境中使用 jconsole

无论如何,jvisualvm 都是一个更好的工具。我不会使用 jconsole 除非你不得不这样做。

我如何将十六进制转换(java代码会超级)到java long?

long idFind = Long.parseLong(thrdId, 16);

你能告诉我为什么这不起作用

要么你没有从同一个进程运行它,要么线程捕获了ThreadDeath你触发的错误。

于 2012-09-04T07:34:52.047 回答