java-我如何才能获得未来';TimeoutException上的s堆栈跟踪

java-我如何才能获得未来';TimeoutException上的s堆栈跟踪,java,multithreading,executorservice,Java,Multithreading,Executorservice,在java中,我想确定线程的当前堆栈,当TimeoutException发生时,它将填充未来的结果。TimeoutException提供的堆栈跟踪中的顶部条目似乎只指示调用future.get()的位置,而不是后台线程的状态。例如: ExecutorService executor = Executors.newSingleThreadExecutor(); Future<String> future = executor.submit(new Callable<String

在java中,我想确定线程的当前堆栈,当TimeoutException发生时,它将填充未来的结果。TimeoutException提供的堆栈跟踪中的顶部条目似乎只指示调用future.get()的位置,而不是后台线程的状态。例如:

ExecutorService executor = Executors.newSingleThreadExecutor();

Future<String> future = executor.submit(new Callable<String>() {
    @Override
    public String call() throws Exception {
        Thread.sleep(10000);
        return "";
    }
});

try {
    future.get(1, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
    e.printStackTrace();
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}
ExecutorService executor=Executors.newSingleThreadExecutor();
Future=executor.submit(new Callable()){
@凌驾
公共字符串调用()引发异常{
睡眠(10000);
返回“”;
}
});
试一试{
get(1,时间单位为毫秒);
}捕获(超时异常e){
e、 printStackTrace();
}捕获(中断异常|执行异常e){
e、 printStackTrace();
}
在本例中,我发现最上面的条目是future.get(1,TimeUnit.millizes)条目,而不是Thread.sleep(10000)。我希望堆栈跟踪指示Thread.sleep(10000),因为这是当前正在执行的。有没有一种优雅的方法


我发现,如果存在实际的执行问题,那么ExecutionException.printStackTrace()将指示问题在后台线程中发生的位置。

您无法获取该异常的跟踪


因为在该异常中没有原因和被抑制的异常。

如果有对正在运行任务的线程的引用t,则可以调用
t.getStackTrace()
;但是标准的library ExecutorService实现不会告诉您哪个线程正在运行该任务

您可以让任务本身记录运行它的线程:

class MyTask implements Callable<String> {
    private volatile Thread executorThread;

    @Override
    String call() {
        executorThread = Thread.currentThread(); // not getCurrentThread()
        Thread.sleep(10000);
        return "";
    }

    Thread getExecutorThread() {
        return executorThread;
    }
}

谢谢你的回复。这与我目前写的非常相似。你可以得到任何异常的堆栈跟踪。问题是,超时异常没有关于池线程的任何信息,因为它没有发生在池线程中。它发生在主线程中。池线程中没有异常。池线程仍在愉快地运行,这时主线程变得不耐烦,不再等待它完成。
...
MyTask myTask = new MyTask();
Future<String> future = executor.submit(myTask);
...
} catch (InterruptedException | ExecutionException e) {
    StackTraceElement[] stack = myTask.getExecutorThread().getStackTrace();
    for (StackTraceElement element : stack) {
        ...print it...
    }
}