欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

打印Java程序的线程栈信息方式

程序员文章站 2022-06-19 18:07:07
打印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;
            }
        };
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。