gpt4 book ai didi

java - 如何在 TimeoutException 上获得 future 的堆栈跟踪

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:11:27 25 4
gpt4 key购买 nike

在 java 中,我想确定当 TimeoutException 发生时填充 future 结果的线程的当前堆栈。似乎 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();
}

在此示例中,我发现顶部条目是 future.get(1, TimeUnit.MILLISECONDS) 条目,而不是 Thread.sleep(10000)。我希望堆栈跟踪指示 Thread.sleep(10000),因为这是当前正在执行的。有没有一种优雅的方式来做到这一点?

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

最佳答案

如果您有一个引用 t,指向正在运行任务的线程,您可以调用 t.getStackTrace();但是标准库 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.getExecutorThread().getStackTrace();

...
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...
}
}

关于java - 如何在 TimeoutException 上获得 future 的堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27552868/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com