0

Мой код работает с submit() для вызова ExecutorService. Но когда я попытался изменить его на invokeAll(), я получаю ошибку компиляции.ExecutorService работает нормально с отправкой, но ошибка бросания для invokeAll

код:

public class FutureDemo{ 
    public FutureDemo(){ 
     ExecutorService service = Executors.newFixedThreadPool(10); 
     /* 
     for (int i=0; i<10; i++){ 
      MyCallable myCallable = new MyCallable((long)i); 
      Future<Long> futureResult = service.submit(myCallable); 
      Long result = null; 
      try{ 
       result = futureResult.get(5000, TimeUnit.MILLISECONDS); 
      }catch(TimeoutException e){ 
       System.out.println("Time out after 5 seconds"); 
       futureResult.cancel(true); 
      }catch(InterruptedException ie){ 
       System.out.println("Error: Interrupted"); 
      }catch(ExecutionException ee){ 
       System.out.println("Error: Execution interrupted"); 
      } 
      System.out.println("Result:"+result); 
     } 
     */ 
     List<MyCallable> futureList = new ArrayList<MyCallable>(); 
     for (int i=0; i<10; i++){ 
      MyCallable myCallable = new MyCallable((long)i); 
      futureList.add(myCallable); 
     } 
     try{ 
      Future<Long> futures = service.invokeAll(futureList); // error 
     }catch(Exception err){ 
      err.printStackTrace(); 
     } 
     service.shutdown(); 
    } 
    public static void main(String args[]){ 
     FutureDemo fc = new FutureDemo(); 
    } 
    class MyCallable implements Callable{ 
     Long id = 0L; 
     public MyCallable(Long val){ 
      this.id = val; 
     } 
     public Long call(){ 
      return id; 
     } 
    } 
} 

Ошибка:

FutureDemo.java:31: error: no suitable method found for invokeAll(List<FutureDemo.MyCallable>) 
         Future<Long> futures = service.invokeAll(futureList); // error 
               ^
method ExecutorService.<T#1>invokeAll(Collection<? extends 

Callable<T#1>>,long,TimeUnit) is not applicable 
     (cannot instantiate from arguments because actual and formal argument lists differ in length) 
    method ExecutorService.<T#2>invokeAll(Collection<? extends Callable<T#2>>) is not applicable 
     (no instance(s) of type variable(s) T#2 exist so that argument type List<FutureDemo.MyCallable> conforms to formal parameter type Collection<? extends Callable<T#2>>) 
    where T#1,T#2 are type-variables: 
    T#1 extends Object declared in method <T#1>invokeAll(Collection<? extends Callable<T#1>>,long,TimeUnit) 
    T#2 extends Object declared in method <T#2>invokeAll(Collection<? extends Callable<T#2>>) 
+0

MyCallable реализует Callable JimmyB

+0

Submit работает отлично. –

ответ

2

Для одного invokeAll возвращает List<Future<T>>, но вы пытаетесь присвоить результат переменной типа Future<T>.

Два, вы передаете List<MyCallable> в качестве аргумента, где MyCallable является необработанным Callable. Будучи сырыми, генерические элементы стираются, и компилятор не может вывести соответствующий тип, который бы соответствовал ожидаемому типу параметра Collection<? extends Callable<T>>.

Не используйте необработанные типы. Читать

Затем соответствующим образом изменить объявление класса

class MyCallable implements Callable<Long> { 
+0

Получил это :). Теперь он работает нормально. invokeAll() из ExecutorService & CountdownLatch с countDown почти одинаковы ?. –

+0

@ravindra _nearly same_ в каких отношениях? Нет, я бы не сказал, что «CountdownLatch» и «ExecutorService» одинаковы. –

+0

то же самое в смысле: дают ли они тот же результат? ожидая завершения всех задач в invokeAll и завершения задачи после countDown, становясь Zero. –