簡體   English   中英

java - 如何在TimeoutException上獲得未來的堆棧跟蹤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM