我查看了有关获取线程ID的现有问题,例如java-thread-id-and-stack-trace 。
但我无法弄清楚看似简单的事情。我想创建一个JSP工具来停止Java中的线程。
我知道这一般是一个坏主意,但我们需要它,因为我们不能在我们的环境中使用JConsole导致JBoss的某些强化。
我的问题是,采取样本jstack输出:
Event Batch Processing (Spring UAA/1.0.2)" daemon prio=10 tid=0x0000000041e27800 nid=0x363b waiting on condition [0x00007f9a89267000]
根据{{1}}中定义的哪个ID为thread.getId()
?此行java.lang.Thread
中的最后一个标记是什么?[0x00007f9a89267000]
转换为Java hex
(Java代码将超级)? 你能告诉我为什么这不起作用 - >我从一个挂在永无止境的循环中的线程的jstack中获取了一个十六进制long
。然后我做了这个:
tid=
未找到此输出。输入参数是tid - 在Windows 7 calc,Programmer模式(十六进制)中粘贴,然后单击Dec。
更新
在我的测试代码中,当我创建一个无限循环的JSP时,每隔几万次迭代输出一个char - 然后做一个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>");
}
}
我跑了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...
运行我的JSP时,它无法找到它,因为app容器唯一地命名了线程,我能够找到该线程并在打印时:
id = 000000000d4eb000
我明白了:
out.print("" + cnt + " \"" + thrd.getName() + "\"| id :" + thrd.getId() + "| hex :" + Long.toHexString(thrd.getId()) + "| <br>");
那么jstack显然认为是93 "http-0.0.0.0-8181-4"| id :1389| hex :56d|
93 is the thread number in my internal counter in the loop.
内部JVM所知的发现
0x000000000d4eb000
?最后将JSP更改为按名称搜索并停止该线程。幸运的是,线程名称都不同。但这是一个错误 - 运行Windows,JBoss 4.2,Java 1.6更新32?
答案 0 :(得分:1)
您只能找到并停止自己的主题。我会尝试打断线程,以防它可以正常停止。
通常,停止线程是一个坏主意,因为它可能使应用程序处于不一致或不可恢复的状态。你可以避免这种情况的唯一方法是非常好地理解线程可能正在做的所有事情,在什么情况下修复代码以便它优雅地停止更可能更简单和更好
我们无法在我们的环境中使用jconsole
jvisualvm在任何情况下都是一个更好的工具。我不会使用jousole unles syou必须。
如何将十六进制转换为(java代码会超级)到java long?
long idFind = Long.parseLong(thrdId, 16);
你能告诉我为什么这不起作用
要么你没有从同一个进程运行它,要么线程遇到你触发的ThreadDeath
错误。