[英]java - How can I get a future's stack trace on TimeoutException
在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();
}
在這個例子中,我發現top條目是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...
}
}
你無法獲得該異常的蹤跡。
因為在那個例外中沒有原因和抑制異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.