Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么executor的线程以异常结束时没有用完可用线程?_Java_Multithreading_Threadpool_Executorservice_Threadpoolexecutor - Fatal编程技术网

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

Java 为什么executor的线程以异常结束时没有用完可用线程?,java,multithreading,threadpool,executorservice,threadpoolexecutor,Java,Multithreading,Threadpool,Executorservice,Threadpoolexecutor,在下面的场景中,我的任务抛出一个异常。我是例外,在一个请求之后,我的池将无法处理任何进一步的请求,但它不会发生。线程池在此场景中的行为如何?异常如何从池线程到主应用程序线程进行通信 public class CallableClass implements Callable<String> { @Override public String call() throws Exception { throw new RuntimeException();

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

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

  }
public类CallableClass实现可调用{
@凌驾
公共字符串调用()引发异常{
抛出新的RuntimeException();
}
}
课堂测试{
ExecutorService executor=Executors.newFixedThreadPool(1);
public void execute(){
试一试{
系统输出打印项次(执行人);
Future=executor.submit(新任务());
系统输出打印项次(执行人);
future.get();
}捕获(例外e){
系统输出打印项次(执行人);
e、 printStackTrace();
}
}
}

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

@Override
public String call() throws Exception {
    System.out.println(Thread.currentThread().getName());
    ...
}
  • 线程池在此场景中的行为如何
  • 工作进程将其工作时发生的异常通知executor服务。但是没有理由从
    ThreadPoolExecutor#workers
    集中删除该worker。如有需要,它将继续工作

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

    如果任何线程在关机之前的执行过程中由于故障而终止,那么如果需要执行后续任务,将使用一个新线程代替它

    [JDK 9]


  • 异常如何从池线程到主应用程序线程进行通信
  • Callable 35;调用
    引发的任何异常都将被
    ExecutionException
    包装,并弹出给调用方:

    @如果计算引发异常,则引发执行异常

    [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.");
        }
    }
    

    您好,Andrew,我将任务代码更新为:类任务实现可调用的{@Override public String call()抛出异常{System.out.println(Thread.currentThread()+“>>>>>>>>>>>>>>>>”+Thread.currentThread().getName());抛出新的RuntimeException();},但对于每个请求,它都打印相同的线程名称。这意味着即使在执行上一个任务时发生异常,也会重复使用同一个worker。“从可调用的#调用引发的任何异常都会被ExecutionException包装并弹出到调用方”。很抱歉,我没有得到这个。@Jaraws,它向调用
    get
    的线程抛出一个
    newexecutionexception(yourActualException)
    。然后您通过
    exception.getCause()
    Hello@Andrew调用fetch
    yourActualException
    by
    exception.getCause()
    Hello@Andrew,如果池线程抛出异常,则池必须耗尽其唯一的线程。因为这里没有发生这种情况,所以这个池线程必须通过某个通道将其异常传递给主线程并返回到其池。@Jaraws,线程池从不抛出异常,您的任务可能会抛出异常