2014-04-07 22 views
3

我工作的這個代碼示例:開創了ExecutorService的的invokeAll()的包裝

ExecutorService executorService = Executors.newSingleThreadExecutor(); 

Set<Callable<String>> callables = new HashSet<Callable<String>>(); 

callables.add(new Callable<String>() { 
    public String call() throws Exception { 
     return "Task 1"; 
    } 
}); 
callables.add(new Callable<String>() { 
    public String call() throws Exception { 
     return "Task 2"; 
    } 
}); 
callables.add(new Callable<String>() { 
    public String call() throws Exception { 
     return "Task 3"; 
    } 
}); 

List<Future<String>> futures = executorService.invokeAll(callables); 

for(Future<String> future : futures){ 
    System.out.println("future.get = " + future.get()); 
} 

executorService.shutdown(); 

我試圖寫一個包裝類此代碼,將用於通用型工作,可以投在展開時爲String/int/etc。

我遇到的問題是,收集傳遞給invokeAll()方法。我在將自定義活動添加到可設置集中時遇到了一些麻煩。

理想我希望能夠分離出我的代碼,這樣我可以調用的方法,而不是聲明一個內部類。有沒有一種方法來聲明從我的自定義方法返回的對象集合,這些對象可以傳遞給invokeAll()方法?

我嘗試了幾個不同的集合,但不斷得到:

The method invokeAll(Collection<? extends Callable<T>>) in the type ExecutorService is not applicable for the arguments (Collection<Object>) 
+1

你可以發佈你到目前爲止的代碼嗎?導致這個錯誤的那個? – njzk2

回答

2

因爲invokeAll()Generic Method,您可能需要使用特殊的語法來表示他們鍵入T是。下面的調用應該清理你的錯誤:

List<Future<String>> futures = executorService.<String>invokeAll(callables); 

雖然我不得不說,我是能夠運行您的示例代碼,是一個獨立的程序...

通常情況下,這不是一個問題,但如果使用類型推斷定義集合(可從Java 7開始),則可能會成爲問題。例如,如果你的方式初始化你的Collection

Set<Callable<String>> callables = new HashSet<>(); 

這意味着編譯器可能有工作有點難以弄清楚您的收藏的類型(儘管這也爲我工作)。這可能尤其如此,因爲你聲稱你正在嘗試編寫一個通用的包裝類。通用方法的詭計幾乎肯定會起作用。您可能還想查看關於通用方法的Java教程this