简体   繁体   中英

java - How can I get a future's stack trace on TimeoutException

In java, I would like to determine the current stack of the thread which populates the result of the future when a TimeoutException occurs. It seems that the top entry in the stack trace provided by a TimeoutException only indicates where future.get() was invoked, not the state of the background thread. For example:

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();
}

In this example I've found that the top entry is the future.get(1, TimeUnit.MILLISECONDS) entry, not the Thread.sleep(10000). I would like the stack trace to indicate Thread.sleep(10000) since this is what is currently being executed. Is there an elegant way of doing this?

I've found that if there is an actual execution problem, then the ExecutionException.printStackTrace() will indicate where the problem occurred in the background thread.

If you had a reference, t, to the Thread was running the task, you could call t.getStackTrace() ; but the standard library ExecutorService implementations aren't going to tell you what thread is running the task.

You could have the task itself record what thread is running it:

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

That way, when your main thread times out, it could call 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...
    }
}

You cant get the trace of that exception.

Because In that exception doesnt have cause and suppressed exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM