Why does parallelism ForkJoinPool double my exception?

Assuming I have code as shown below:

Future<Object> executeBy(ExecutorService executor) {
    return executor.submit(() -> {
        throw new IllegalStateException();
    });
}

no problem when using ForkJoinPool#commonPool, but when I use parallelism ForkJoinPool, it will double the value IllegalStateException. eg:

executeBy(new ForkJoinPool(1)).get(); 
//                              ^--- double the IllegalStateException

Q1 : why does parallelism ForkJoinPooldouble the value Exceptionin Callable?

Q2 : How to avoid this strange behavior?

+4
source share
2 answers

/ , . , "". , .

. , . ,

static Future<Object> executeBy(ExecutorService executor) {
    return executor.submit(() -> {
        throw new IllegalStateException(Thread.currentThread().toString());
    });
}

, , get() , . , /, .

, , F/J, , :

static Future<Object> executeBy(ExecutorService executor) {
    return executor.submit(() -> {
        throw new IllegalStateException() {
                @Override
                public String toString() {
                    String s = getClass().getSuperclass().getName();
                    String message = getLocalizedMessage();
                    return message!=null? s+": "+message: s;
                }
            };
    });
}
+10

ForkJoinPool ForkJoinTask .

ForkJoinTask . javadoc

, , , , ( , , ex.printStackTrace()) , , , ; .

private

/**
 * Returns a rethrowable exception for the given task, if
 * available. To provide accurate stack traces, if the exception
 * was not thrown by the current thread, we try to create a new
 * exception of the same type as the one thrown, but with the
 * recorded exception as its cause. If there is no such
 * constructor, we instead try to use a no-arg constructor,
 * followed by initCause, to the same effect. If none of these
 * apply, or any fail due to other exceptions, we return the
 * recorded exception, which is still correct, although it may
 * contain a misleading stack trace.
 *
 * @return the exception, or null if none
 */
private Throwable getThrowableException() {

, IllegalStateException , IllegalStateException, Throwable, IllegalStateException ( ExecutionException).

get.

ForkJoinPool ExecutorService, , , , , .

+8

Source: https://habr.com/ru/post/1679903/


All Articles