【问题标题】:java executor framework's invokeAll equivalent method in spring executorjava executor框架在spring executor中的invokeAll等价方法
【发布时间】:2016-11-14 07:57:01
【问题描述】:

在 java 执行器框架中等待所有任务完成,我们有 invokeAll() 方法。但是在使用 spring 的 ThreadPoolTaskExecutor 时,我们只有返回 Future 对象的提交方法。所以在完成第一个任务后它会继续要开始下一个任务。所以如果我想等到所有任务完成,有什么办法吗?意思是spring有什么方法可以用等于invokeAll()如果我的理解有误请指正..

【问题讨论】:

  • 也许不是,我检查了所有的类都包含 invokeAll() 方法,但它们都指向 java.util.concurrent 包类。

标签: spring multithreading executor


【解决方案1】:

您可以使用 org.springframework.core.task.support.ExecutorServiceAdapter 包装您的 TaskExecutor:

ExecutorServiceAdapter adapter = new ExecutorServiceAdapter(taskExecutor);

List<Future<V>> futures = adapter.invokeAll(tasks);

希望对你有帮助。

【讨论】:

  • 在你看来,这个问题回到java而不是spring,我认为你应该更多地考虑ThreadPoolTaskExecutorExecutorServiceAdapter之间的关系。
  • @Crabime ExecutorServiceAdapter 与spring框架有关?
【解决方案2】:

总是无法进入ThreadPoolTaskExecutor 源代码让我很愚蠢。你提醒我ExecutorServiceAdapter是否属于春天。现在我认为是的,这是我的代码来回答你的问题,希望没有错。

ThreadPoolTaskExecutor threadPool = atx.getBean("threadPool", ThreadPoolTaskExecutor.class);
    ExecutorServiceAdapter adapter = new ExecutorServiceAdapter(threadPool);
    List<Callable<Integer>> tasks = new ArrayList<>();
    Callable<Integer> task = null;
    for (int i = 0; i < 10; i++){
        task = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int time = new Random().nextInt(1000);
                Thread.sleep(100);
                System.out.println(Thread.currentThread().getName() + " has slept " + time);
                return time;
            }
        };
        //submit task and wait to execute
        threadPool.submit(task);
        //add all task to list
        tasks.add(task);
    }

    //get the start time of all threads
    long start = System.currentTimeMillis();
    try {
        List<Future<Integer>> result = adapter.invokeAll(tasks);
        for (int i = 0; i < result.size(); i++){
            System.out.println(result.get(i).get());
        }
    } catch (ExecutionException ex){
        ex.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("Total time is " + (System.currentTimeMillis() - start));

【讨论】:

    【解决方案3】:

    最简单的方法

    taskExecutor.getThreadPoolExecutor().invokeAll(callables);
    

    【讨论】:

      【解决方案4】:

      另一种不使用替代方法实现相同结果的方法是使用 for 循环中的提交。

      这种方法帮助我实现了我想要做的事情。希望这会有所帮助。

      List<Future<String>> list = new ArrayList<Future<String>>();
          Callable<String> callable = new MyTask();
      
          for(int i=0; i< 5; i++){
              //submit Callable tasks to be executed by thread pool
              Future<String> future = executor.submit(callable);
              //add Future to the list, we can get return value using Future
              list.add(future);
          }
      
          for(Future<String> future : list){
              try {
                  //Here future.get() will wait for task to be completed.
                  //Hence small delay will come.
                  System.out.println(future.get());
              }catch (Exception e){
      
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-21
        • 1970-01-01
        • 2021-04-18
        • 2020-01-24
        相关资源
        最近更新 更多