Why a parallelism ForkJoinPool double my exception?

前端 未结 2 1752
旧巷少年郎
旧巷少年郎 2021-01-03 05:11

assuming I have the code like as below:

Future executeBy(ExecutorService executor) {
    return executor.submit(() -> {
        throw new Il         


        
      
      
      
2条回答
  •  死守一世寂寞
    2021-01-03 05:49

    The Fork/Join pool generally attempts to recreate the exception within the caller’s thread if the exception has been thrown in a worker thread and sets the original exception as its cause. This is what you perceived as “doubling”. When you look closer at the stack traces, you will notice the difference between these two exceptions.

    The common pool is not different in that regard. But the common pool allows the caller thread to participate in the work when waiting for the final result. So when you change you code to

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

    you will notice that it often happens that the caller thread is faster in calling get() and do work-stealing within that method than a worker thread can pick up the task. In other words, your supplier has been executed within the main/caller thread and in this case, the exception will not be recreated.

    This feature can easily disabled by throwing an exception type which has no matching public constructor the F/J could use, like with this neat inner class:

    static Future 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;
                    }
                };
        });
    }
    
        

    提交回复
    热议问题