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 如何使用invokeAll()让所有线程池都完成任务?_Java_Multithreading_Arraylist_Executorservice_Future - Fatal编程技术网

Java 如何使用invokeAll()让所有线程池都完成任务?

Java 如何使用invokeAll()让所有线程池都完成任务?,java,multithreading,arraylist,executorservice,future,Java,Multithreading,Arraylist,Executorservice,Future,ExecutorService的工作方式是,当您调用invokeAll时,它会等待所有任务完成: 执行给定的任务,返回保存任务的未来列表 全部完成时的状态和结果。Future.isDone()对于每个 返回的列表的元素请注意,已完成的任务可能 正常终止或通过引发异常终止。结果 如果给定集合在 此操作正在进行中。(重点已添加) 这意味着您的任务都已完成,但有些任务可能引发了异常。此异常是未来的一部分-调用获取会导致异常被重新包装在执行异常中 从你这里开始 java.util.concurrent.

ExecutorService
的工作方式是,当您调用
invokeAll
时,它会等待所有任务完成:

执行给定的任务,返回保存任务的未来列表 全部完成时的状态和结果。Future.isDone()对于每个 返回的列表的元素请注意,已完成的任务可能 正常终止或通过引发异常终止。结果 如果给定集合在 此操作正在进行中。(重点已添加)

这意味着您的任务都已完成,但有些任务可能引发了异常。此异常是
未来
的一部分-调用
获取
会导致异常被重新包装在
执行异常

从你这里开始

java.util.concurrent.ExecutionException: java.lang.NullPointerException at 
java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source) at  
java.util.concurrent.FutureTask.get(Unknown Source) at 
com.mmt.freedom.cheapestfare.TestHotel.main(TestHotel.java:6‌​5)

Caused by: java.lang.NullPointerException at 
com.mmt.freedom.cheapestfare.HotelCheapestFare.getHotelCheap‌estFare(HotelCheapes‌​tFare.java:166) 
at com.mmt.freedom.cheapestfare.HotelCheapestFare.call(HotelChe‌​apestFare.java:219)
at com.mmt.freedom.cheapestfare.HotelCheapestFare.call(HotelChe‌​apestFare.java:1) 
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) atjava.util.concurrent.ThreadPoolExecutor$Worker.run(Unknow‌​n Source)
at java.lang.Thread.run
在本例中,我有一个任务在
ExecutorCompletionService
上调用
take
,该任务在
ExecutorCompletionService
可用时获取
未来的
,然后我将任务提交给
ExecutorCompletionService

这将允许您在失败的任务失败后立即获取失败的任务,而不必等待所有任务一起失败或成功


唯一复杂的是,很难告诉轮询线程所有任务都已完成,因为现在所有任务都是异步的。在本例中,我使用了100个任务将被提交的知识,因此它只需要轮询100次。更一般的方法是从
submit
方法中收集
Future
s,然后循环查看是否所有操作都已完成。

invokeAll是一种阻塞方法。这意味着,在所有线程完成之前,JVM不会继续下一行。所以我认为你的线程将来的结果有问题

public static void main(String[] args) throws Exception {
    final ExecutorService executorService = Executors.newFixedThreadPool(10);
    final ExecutorCompletionService<String> completionService = new ExecutorCompletionService<>(executorService);
    executorService.submit(new Runnable() {
        @Override
        public void run() {
            for (int i = 0; i < 100; ++i) {
                try {
                    final Future<String> myValue = completionService.take();
                    //do stuff with the Future
                    final String result = myValue.get();
                    System.out.println(result);
                } catch (InterruptedException ex) {
                    return;
                } catch (ExecutionException ex) {
                    System.err.println("TASK FAILED");
                }
            }
        }
    });
    for (int i = 0; i < 100; ++i) {
        completionService.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                if (Math.random() > 0.5) {
                    throw new RuntimeException("FAILED");
                }
                return "SUCCESS";
            }
        });
    }
    executorService.shutdown();
}
从这一行开始,我认为有一些期货没有结果,可以为null,所以你应该检查你的代码,如果有一些期货为null,如果是,在执行这一行之前,得到一个if。

抛出下面的异常

取消异常
-如果计算被取消

ExecutionException
-如果计算引发异常

InterruptedException
-如果当前线程在等待时被中断

调用
get()
方法时捕获所有这些异常

我已经模拟了一些
可调用
任务的除零异常,但是如果捕获到示例代码中所示的上述三个异常,则一个
可调用
中的异常不会影响提交给
ExecutorService
的其他
可调用
任务

示例代码段:

System.out.println("name is:"+future.get(i).get().getName());
import java.util.concurrent.*;
导入java.util.*;
公共类InvokeAllUsage{
公共InvokeAllUsage(){
System.out.println(“创建服务”);
ExecutorService=Executors.newFixedThreadPool(10);
List futureList=新建ArrayList();

for(int i=0;iInvokeAll应该等到所有可调用项都完成。你能添加异常和堆栈跟踪吗?内部一些线程在完成之前进入for循环并抛出异常请帮助我我必须根据你的堆栈跟踪提交任务:
com.mmt.freedom.cheapestfare.HotelCheapestFare.getHotelCheapestFare(便宜旅馆‌​tFare.java:166)
。错误应该在那里。此时我有一个列表,但当我调试它时,我得到了我的列表。我可以将ExecutorCompletionService与可调用列表一起使用吗objects@SahilKohli不,这没有任何意义。您在
执行器服务
中使用
集合的原因是,您可以等待它们全部完成,然后再继续处理2.使用“ExecutorCompletionService”,您正在轮询是否完成,因此一次提交或在循环中提交都没有区别。我的任务非常耗时,因此我希望它们同时运行,以便它们同时运行,并在线程完成后获得我的未来结果。在这种情况下,您可以使用
invokeAll
ExecutorService
的方法,并像您当前所做的那样处理所有的
未来的
s。使用
ExecutorCompletionListener
的原因是每个任务完成后都会通知您。这是两件不同的事情。我不明白您想要什么;您可以在每个结果发生时进行处理或者在最后处理所有内容。在任何一种情况下,您都需要处理可能的
ExecutionException
s。是的,我希望forloop仅在完成invokeall()之后才能工作但是它在一个或两个线程完成后才工作,所以请告诉我如何防止我的for循环,使它只在列表完成后执行。这是非常错误的。看看stacktrace,
Future.get
方法抛出一个
exectuionexception
,这很明显。结果不是
null
>Callable
调用
方法中遇到了
NullPointerException
。这在
未来
中被捕获,然后被包装在
ExecutionException
中。很抱歉,我错过了java.util.concurrent.ExecutionException,因此是未来的代码获得此异常。因此其他更好的解决方案很好的解释n+1,那么使用service.invokeAll(futureList)还是与service.submit一起递归(new Runnable)更好?这两种方法的执行时间是否有显著差异?或者只是为了不同的目标,即返回值?当您需要等待所有任务的结果时,请使用invokeAll。否则,您可以使用任务提交。
public static void main(String[] args) throws Exception {
    final ExecutorService executorService = Executors.newFixedThreadPool(10);
    final ExecutorCompletionService<String> completionService = new ExecutorCompletionService<>(executorService);
    executorService.submit(new Runnable() {
        @Override
        public void run() {
            for (int i = 0; i < 100; ++i) {
                try {
                    final Future<String> myValue = completionService.take();
                    //do stuff with the Future
                    final String result = myValue.get();
                    System.out.println(result);
                } catch (InterruptedException ex) {
                    return;
                } catch (ExecutionException ex) {
                    System.err.println("TASK FAILED");
                }
            }
        }
    });
    for (int i = 0; i < 100; ++i) {
        completionService.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                if (Math.random() > 0.5) {
                    throw new RuntimeException("FAILED");
                }
                return "SUCCESS";
            }
        });
    }
    executorService.shutdown();
}
System.out.println("name is:"+future.get(i).get().getName());
import java.util.concurrent.*;
import java.util.*;

public class InvokeAllUsage{
    public InvokeAllUsage(){
        System.out.println("creating service");
        ExecutorService service = Executors.newFixedThreadPool(10);

        List<MyCallable> futureList = new ArrayList<MyCallable>();
        for ( int i=0; i<10; i++){
            MyCallable myCallable = new MyCallable((long)i+1);
            futureList.add(myCallable);
        }
        System.out.println("Start");
        try{
            List<Future<Long>> futures = service.invokeAll(futureList);  
            for(Future<Long> future : futures){
                try{
                    System.out.println("future.isDone = " + future.isDone());
                    System.out.println("future: call ="+future.get());
                }
                catch (CancellationException ce) {
                    ce.printStackTrace();
                } catch (ExecutionException ee) {
                    ee.printStackTrace();
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt(); // ignore/reset
                }
            }
        }catch(Exception err){
            err.printStackTrace();
        }
        System.out.println("Completed");
        service.shutdown();
    }
    public static void main(String args[]){
        InvokeAllUsage demo = new InvokeAllUsage();
    }
    class MyCallable implements Callable<Long>{
        Long id = 0L;
        public MyCallable(Long val){
            this.id = val;
        }
        public Long call(){

            if ( id % 5 == 0){
                id = id / 0;
            }           
            return id;
        }
    }
}
creating service
Start
future.isDone = true
future: call =1
future.isDone = true
future: call =2
future.isDone = true
future: call =3
future.isDone = true
future: call =4
future.isDone = true
java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
        at InvokeAllUsage.<init>(InvokeAllUsage.java:20)
        at InvokeAllUsage.main(InvokeAllUsage.java:37)
Caused by: java.lang.ArithmeticException: / by zero
        at InvokeAllUsage$MyCallable.call(InvokeAllUsage.java:47)
        at InvokeAllUsage$MyCallable.call(InvokeAllUsage.java:39)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)
future.isDone = true
future: call =6
future.isDone = true
future: call =7
future.isDone = true
future: call =8
future.isDone = true
future: call =9
future.isDone = true
java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:188)
        at InvokeAllUsage.<init>(InvokeAllUsage.java:20)
        at InvokeAllUsage.main(InvokeAllUsage.java:37)
Caused by: java.lang.ArithmeticException: / by zero
        at InvokeAllUsage$MyCallable.call(InvokeAllUsage.java:47)
        at InvokeAllUsage$MyCallable.call(InvokeAllUsage.java:39)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)
Completed