有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么executor的线程以异常结束时没有用完可用线程?

在下面的场景中,我的任务抛出一个异常。我是例外,在一个请求之后,我的池将无法处理任何进一步的请求,但它不会发生。线程池在这种情况下的行为如何?异常如何从池线程到主应用程序线程进行通信

public class CallableClass implements Callable<String> {

    @Override
    public String call() throws Exception {
        throw new RuntimeException();
    }

}

class Test {
      ExecutorService executor = Executors.newFixedThreadPool(1);

      public void execute(){  
         try {
            System.out.println(executor);
            Future<String> future = executor.submit(new Task());
            System.out.println(executor);

            future.get();
        }catch(Exception e) {
           System.out.println(executor);
           e.printStackTrace();
        }
     }

  }

共 (1) 个答案

  1. # 1 楼答案

    您可以通过打印当前正在执行的线程的名称来检查它:

    @Override
    public String call() throws Exception {
        System.out.println(Thread.currentThread().getName());
        ...
    }
    
    1. How does thread pool behaves in this scenario?

    工作进程将其工作时发生的异常通知executor服务。但是没有理由从ThreadPoolExecutor#workers集中删除该工作者。如果有必要,它将继续工作

    您不应该看到executor服务的任何故障。如果发生错误,它将用有效的工作线程(或线程)替换无效的工作线程:

    If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.

    ExecutorService.newFixedThreadPool(int) [JDK 9]


    1. How communication of exception happens from Pool thread to main application thread?

    Callable#call抛出的任何异常都被ExecutionException包装,并弹出给调用方:

    @throws ExecutionException if the computation threw an exception

    Future.get() [JDK 9]

    检查ExecutionException#getCause是否为RuntimeException实例的示例:

    } catch (ExecutionException e) { 
        Throwable cause = e.getCause();
        if (cause != null && cause instanceof RuntimeException) {
            System.out.println("A RuntimeException was thrown.");
        }
    }