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

JavaExecutorService调用所有多个任务解析

厍建义
2023-03-14

我正在使用执行器服务并行运行任务。并行运行方法采用输入整数并返回整数 。由于并行任务具有返回类型,因此我使用了可调用的匿名类。您可以在下面的示例中看到 ExecutorServiceExample task(int i ) 是从 executer 调用的。任务方法也有1秒的等待时间,并为i==7抛出异常;

在下面的实现中,我使用invokeAll和isDone,并尝试收集数据

下面的程序抛出IllegalMonitorStateException

未来任务迭代和检查有什么问题 isDone 和 get() 。如何处理特定调用的异常。我想并行运行所有1到14个任务,并在所有完成时收集返回类型。另外,在错误的情况下,要知道输入,它给出了异常(7和14)

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

class MyException extends Exception{
    MyException(String message) {
        super(message);
    }
}

public class ExecutorServiceExample {

    public int task(int i) throws MyException, InterruptedException {
        System.out.println("Running task.."+i);
        wait(1000);
        if(i%7==0) {
            throw new MyException("multiple of 7 not allowed");
        }

        return i;
    }

    public static void main(String[] args) {

        ExecutorService executorService = Executors.newFixedThreadPool(10);

        List<Callable<Integer>> tasks = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14).stream().map(id->{
           return new Callable<Integer>() {
               @Override
               public Integer call() throws Exception {
                   ExecutorServiceExample executorServiceExample = new ExecutorServiceExample();
                   return executorServiceExample.task(id);
               }
           };
        }).collect(Collectors.toList());
        
        try{
            List<Future<Integer>> results = executorService.invokeAll(tasks);

            for (Future<Integer> task: results) {
                if(task.isDone()){
                    System.out.println(task.get());
                }
            }

        }catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }finally {
            executorService.shutdown();
        }
    }
}

共有2个答案

施自怡
2023-03-14

我不知道你为什么要这样设计它。但是很明显,它有很多问题。i/7==0或i%7==0示例不是锁,所以为什么要使用等待?“调用所有”返回的期货必须完成,但可能会在调用get时获得异常。这是你想要的吗?

import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

class MyException extends Exception {
    MyException(String message) {
        super(message);
    }
}

public class ExecutorServiceExample {

    public int task(int i) throws MyException, InterruptedException {
        TimeUnit.MILLISECONDS.sleep(1000);
        if (i % 7 == 0) {
            throw new MyException("multiple of 7 not allowed");
        }

        return i;
    }

    public static void main(String[] args) throws InterruptedException {

        ExecutorService executorService = Executors.newFixedThreadPool(10);

        List<Callable<Integer>> tasks = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
                .map(id -> (Callable<Integer>) () -> {
                    ExecutorServiceExample executorServiceExample = new ExecutorServiceExample();
                    return executorServiceExample.task(id);
                }).collect(Collectors.toList());
        List<Future<Integer>> results = executorService.invokeAll(tasks);
        executorService.shutdown();
        for (Future<Integer> task : results) {
            try {
                System.out.println(task.get());
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }


    }
}
柯天宇
2023-03-14

事实上,每个任务都会产生一个<code>IllegalMonitorStateException</code>因为在<code>synchronized</code>块中没有调用<code>wait</code>方法:Illegal MonitorStateExeption on wait()调用。也许你应该使用睡眠,而不是等待

ExecutionException未来#get抛出。因此,如果您缩小try-catch的范围,实际上将捕获14个异常

           for (Future<Integer> task: results) {
                try {
                    System.out.println(task.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
 类似资料:
  • 问题内容: 等待所有任务完成的最简单方法是什么?我的任务主要是计算,所以我只想运行大量的作业-每个内核上一个。现在,我的设置如下所示: 实现可运行。这似乎是正确执行的任务,但代码崩溃上用。这很奇怪,因为我玩了一些玩具示例,而且看起来很奏效。 包含数以万计的元素。我应该使用其他方法吗?我正在寻找尽可能简单的东西 问题答案: 最简单的方法是使用单行代码执行所需的操作。用你的话来说,你需要修改或包装以实

  • 问题内容: 我正在寻找可以提供超时的ExecutorService实现。如果提交到ExecutorService的任务花费的时间超过了超时时间,则这些任务将被中断。实现这样的野兽并不是一个困难的任务,但是我想知道是否有人知道现有的实现。 这是我根据以下一些讨论得出的。任何意见? 问题答案: 你可以为此使用ScheduledExecutorService。首先,你只提交一次即可立即开始,并保留创建的

  • 我试着用一个实例并行运行许多计划任务,每一个我这样配置任务 但是有很多实例每秒开始,而第一个实例尚未完成。是否可以同时配置任务运行的一个实例?我的豆子配置在Spring调度器.xml

  • 我正在将一些用于iOS和OSX的Ant构建转换为Gradle。创建了以下内容: 这可能很简单,但我做错了什么?如何从自定义类中调用exec任务?

  • 我在用Gradle。我有两个任务:“A”和“B”。我想让任务“A”调用任务“B”。我怎么能这么做? 是否可以简单地从现有任务中调用另一个任务?

  • 我在Scala上使用Play 2.5,我创建了一个类,可以多次调用外部web服务。 外部Web服务在某些条件下被调用并得到ok或nok的简单响应。如果可以,那么我应该更新内部对象状态,如果可以,我现在什么也不做。 这是我的类,它将String的列表作为参数,并返回要在控制器中处理的对象的Future列表。 是列表类型的列表,但我希望它只是一个简单的响应列表。 1)如何简化和纠正我的代码以获得响应列