当前位置: 首页 > 知识库问答 >
问题:

如果线程列表中的任何一个线程出现异常,则中断所有线程

别烨熠
2023-03-14

我正在使用invokeAll()调用线程列表。AFAIK invokeAll()仅在所有线程完成其任务时才返回。

ExecutorService threadExecutor = Executors.newFixedThreadPool(getThreadSize());
List<Future<Object>> future = w_threadExecutor.invokeAll(threadList);

当所有线程完成时调用

for (Future<Object> w_inProgressThread : w_future)
{
//

它将停止发生异常的线程,而不停止其余的线程。如果任何一个线程抛出异常,是否有一种方法可以停止所有其他线程?或者我必须提交每个任务而不是invokeAll()??

CompletionService<Object> completionService = new ExecutorCompletionService<Object>(w_threadExecutor);
                List<Future<Object>> futures = new ArrayList<Future<Object>>();
                for(Thread w_mt : threadList)
                {
                 futures.add(completionService.submit(w_mt));
                }
                for (int numTaken = 0; numTaken < futures.size(); numTaken++) {
                    Future f = completionService.take();
                    try {
                      Object result = f.get();
                      System.out.println(result);  // do something with the normal result
                    } catch (Exception e) {
                      System.out.println("Catched ExecutionException, shutdown now!");
                      //threadExecutor.shutdownNow();
                      Thread.currentThread().interrupt();

                      for (Future<Object> inProgressThread : futures)
                         {
                             inProgressThread.cancel(true);
                         } 
                      break;
                    }

按照沃尔特苏的建议,我试着

ExecutorService threadExecutor = Executors.newFixedThreadPool(3);
              CompletionService<Object> completionService = new ExecutorCompletionService<Object>(threadExecutor);
              List<Future<Object>> futures = new ArrayList<Future<Object>>();
              futures.add(completionService.submit(new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                    String s=null;
                //  Thread.sleep(1000);
                  for(int i=0; i < 1000000; i++){
                        int j =10 ;
                        if(i==100)
                        {

                        s.toString();
                        }

                        System.out.println("dazfczdsa :: " + i);
                    }
                  //throw new Exception("This is an expected Exception");
                return s;
                }
              }));
              futures.add(completionService.submit(new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                    for(int i=0; i < 1000000; i++){
                        int j =0 ;
                        j= j+2;
                        System.out.println("dasa :: " + i);
                    }
                  Thread.sleep(3000);

                  return "My First Result";
                }
              }));

              while (futures.size() > 0) {
                Future f = completionService.take();
                futures.remove(f);
                try {
                  Object result = f.get();
                  System.out.println(result);  // do something with the normal result
                } catch (ExecutionException e) {
                  System.out.println("Caught exception from one task: " + e.getCause().getMessage() + ". shutdown now!");
                  f.cancel(true);
                  threadExecutor.shutdownNow();
                  break;
                }
              }
              System.out.println("Main exists");

发生异常时,此操作不会停止

共有1个答案

柴寂离
2023-03-14

您必须逐个submit(),而不是invokeAll(),然后检查Future是否有异常。

public static void main(String[] args) throws InterruptedException {
  ExecutorService threadExecutor = Executors.newFixedThreadPool(3);
  CompletionService<Object> completionService = new ExecutorCompletionService<>(threadExecutor);
  List<Future<Object>> futures = new ArrayList<>();
  futures.add(completionService.submit(new Callable<Object>() {
    @Override
    public Object call() throws Exception {
      Thread.sleep(1000);
      throw new Exception("This is an expected Exception");
    }
  }));
  futures.add(completionService.submit(new Callable<Object>() {
    @Override
    public Object call() throws Exception {
      Thread.sleep(3000);
      return "My First Result";
    }
  }));

  while (futures.size() > 0) {
    Future f = completionService.take();
    futures.remove(f);
    try {
      Object result = f.get();
      System.out.println(result);  // do something with the normal result
    } catch (ExecutionException e) {
      System.out.println("Caught exception from one task: " + e.getCause().getMessage() + ". shutdown now!");
      threadExecutor.shutdownNow();
      break;
    }
  }
  System.out.println("Main exists");
}

更新1:(回答OP的更新1问题)

这是因为您的任务有一个不检查中断的长循环,这使您的任务不可取消。那你怎么阻止它?我认为你必须修改你的其他任务,使他们可以取消。正如官方文件所说:

for (int i = 0; i < inputs.length; i++) {
    heavyCrunch(inputs[i]);
    if (Thread.interrupted()) {
        // We've been interrupted: no more crunching.
        return;
    }
}
 类似资料:
  • 我在线程“main”java中遇到异常。错误:未解析编译。 我做错了什么? 线程“main”中出现异常: java.lang.错误:未解决的编译问题: 对于类型在

  • 我从GitHub克隆了我的项目,现在我无法运行我的项目。 我收到以下错误: 知道是什么导致了这个错误吗? 编辑 我检查了这个问题Intellij在我发布到这里之前突然抛出ClassNotFoundException,它没有给我任何解决方案...为什么要将我的问题标记为重复,因为那个问题不能解决我的问题?

  • 我得到了这个错误: 线程“main”Java.lang.NosuchFielderRror:calificacion.main处的num1异常(problema_3.Java:17) 在这个简单的终端Java程序上键入第一个值后: 另一方面,这一个运行良好,我使用相同的输入法在这两个: 提前道谢。

  • 当我从nextInt()获取输入时,扫描器会抛出异常,但是如果我从nextLine()获取输入,然后将其解析为int,那么我的代码会正常运行。 如果可以将字符串输入解析为任何类型,为什么还要使用nextInt()或nextDouble()。

  • 每当我运行这个函数时,函数与.nextint()中的

  • 但是当我运行它时,我得到以下错误: 线程“main”java.lang.ClassNotFoundException:org.h2.java.net.URLClassLoader$1处的Driver.运行(未知源)java.net.URLClassLoader$1处的运行(未知源)java.security.AccessController.doprivileged(本机方法)java.net.U