web-dev-qa-db-ja.com

invokeAll()を使用してすべてのスレッドプールにタスクを実行させる方法は?

    ExecutorService pool=Executors.newFixedThreadPool(7);
        List<Future<Hotel>> future=new ArrayList<Future<Hotel>>();
        List<Callable<Hotel>> callList = new ArrayList<Callable<Hotel>>();

        for(int i=0;i<=diff;i++){

            String str="2013-"+(liDates.get(i).get(Calendar.MONTH)+1)+"-"+liDates.get(i).get(Calendar.DATE);

            callList.add(new HotelCheapestFare(str));

        }       
     future=pool.invokeAll(callList);
for(int i=0;i<=future.size();i++){

        System.out.println("name is:"+future.get(i).get().getName());
    }

ここで、forループに到達する前にpoolにすべてのタスクをinvokeAllしたいのですが、このループfor forを実行すると、そのinvokeAllの前に実行され、この例外がスローされます。

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
21
user1948313

Future.get() 例外をスローします。

CancellationException-計算がキャンセルされた場合

ExecutionException-計算が例外をスローした場合

InterruptedException-待機中に現在のスレッドが中断された場合

get()メソッドを呼び出すときに、これらすべての例外をキャッチします。

一部のCallableタスクについてゼロ除算の例外をシミュレートしましたが、1つCallableの例外はCallableに送信された他のExecutorServiceタスクに影響しません。サンプルコードに示されている例外。

コードスニペットの例:

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
6
Ravindra babu

invokeAllはブロッキングメソッドです。つまり、すべてのスレッドが完了するまでJVMは次の行に進みません。したがって、スレッドの将来の結果に何か問題があると思います。

System.out.println("name is:"+future.get(i).get().getName());

この行から、結果がなくnullになる先物があると思うので、Futures nullがある場合はコードを確認する必要があります。そうであれば、この行を実行する前にifを取得します。

0
Winston