打印Java程序的线程栈信息方式
程序员文章站
2022-03-07 23:21:37
打印java程序的线程栈信息jstack可以得知当前线程的运行情况安装jstack等命令集,jstack是开发版本jdk的一部分,不是开发版的有可能找不到yum install -y java-1....
打印java程序的线程栈信息
jstack可以得知当前线程的运行情况
安装jstack等命令集,jstack是开发版本jdk的一部分,不是开发版的有可能找不到
yum install -y java-1.8.0-openjdk-devel
查看要打印堆栈的java进程id
jps -l
打印堆栈
sudo -u admin jstack pid > jstack.txt
特别要注意的是jstack需要使用与进程一致的用户才能正确导出堆栈,否则会报错如下
unable to open socket file: target process not responding or hotspot vm not loaded
线程池异常堆栈的坑
import java.util.concurrent.*; public class divtask implements runnable{ int a,b; public divtask(int a, int b) { this.a = a; this.b = b; } @override public void run() { double re = a/b; system.out.println(re); } public static void main(string[] args) throws interruptedexception, executionexception { // threadpoolexecutor executor = new threadpoolexecutor(0, integer.max_value, 0l, timeunit.seconds // , new synchronousqueue<>()); tracethreadpoolexecutor executor = new tracethreadpoolexecutor(0, integer.max_value, 0l, timeunit.seconds , new synchronousqueue<>()); //扩展tracethreadpoolexecutor for (int i = 0; i < 5; i++) { // executor.submit(new divtask(100,i)); //改进方式一: //future re = executor.submit(new divtask(100, i)); //re.get(); //改进方式二: executor.execute(new divtask(100,i)); } //100.0 //25.0 //33.0 //50.0 //其中100/0的异常结果没打印 //线程池很有可能"吃掉程序抛出的异常 //改进方式一: //exception in thread "main" java.util.concurrent.executionexception: java.lang.arithmeticexception: / by zero // at java.util.concurrent.futuretask.report(futuretask.java:122) // at java.util.concurrent.futuretask.get(futuretask.java:192) //。。。 //改进方式二: //exception in thread "pool-1-thread-1" java.lang.arithmeticexception: / by zero // at com.test.divtask.run(divtask.java:15) // at java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1149) // at java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:624) // at java.lang.thread.run(thread.java:748) //100.0 //33.0 //25.0 //50.0 //扩展tracethreadpoolexecutor //java.lang.exception: client stack trace // at com.test.tracethreadpoolexecutor.clienttrace(tracethreadpoolexecutor.java:20) // at com.test.tracethreadpoolexecutor.execute(tracethreadpoolexecutor.java:12) // at com.test.divtask.main(divtask.java:29) //exception in thread "pool-1-thread-1" java.lang.arithmeticexception: / by zero // at com.test.divtask.run(divtask.java:15) // at com.test.tracethreadpoolexecutor.lambda$wrap$0(tracethreadpoolexecutor.java:25) // at java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1149) // at java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:624) // at java.lang.thread.run(thread.java:748) //100.0 //25.0 //33.0 //50.0 } }
import java.util.concurrent.*; /** * 扩展tracethreadpoolexecutor,让它在调度任务前先保存一下提交任务线程的堆栈信息 */ public class tracethreadpoolexecutor extends threadpoolexecutor { public tracethreadpoolexecutor(int corepoolsize, int maximumpoolsize, long keepalivetime, timeunit unit, blockingqueue<runnable> workqueue) { super(corepoolsize, maximumpoolsize, keepalivetime, unit, workqueue); } @override public void execute(runnable task) { super.execute(wrap(task,clienttrace(),thread.currentthread().getname())); } @override public future<?> submit(runnable task) { return super.submit(wrap(task,clienttrace(),thread.currentthread().getname())); } private exception clienttrace(){ return new exception("client stack trace"); } private runnable wrap(final runnable task,final exception clienttrace,string clientthreadname){ return () -> { try { task.run(); } catch (exception e) { clienttrace.printstacktrace(); throw e; } }; } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。