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:65)
Caused by: Java.lang.NullPointerException at
com.mmt.freedom.cheapestfare.HotelCheapestFare.getHotelCheapestFare(HotelCheapestFare.Java:166)
at com.mmt.freedom.cheapestfare.HotelCheapestFare.call(HotelCheapestFare.Java:219)
at com.mmt.freedom.cheapestfare.HotelCheapestFare.call(HotelCheapestFare.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(Unknown Source)
at Java.lang.Thread.run
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
invokeAllはブロッキングメソッドです。つまり、すべてのスレッドが完了するまでJVMは次の行に進みません。したがって、スレッドの将来の結果に何か問題があると思います。
System.out.println("name is:"+future.get(i).get().getName());
この行から、結果がなくnullになる先物があると思うので、Futures nullがある場合はコードを確認する必要があります。そうであれば、この行を実行する前にifを取得します。