[英]Method invokeAll in the type ExecutorService is not applicable for the arguments error
我正在開展一個項目,我將在其中使用不同的Bundles。 讓我們舉個例子,假設我有5個Bundle,每個bundle都有一個方法名稱process
。
以下是我應該做的事情 -
process
方法,然后寫入數據庫。 我不確定這樣做的正確方法是什么? 我應該有五個帖嗎? 每個捆綁一個線程? 但是在那種情況下會發生什么,假設我有50個捆綁,那么我將有50個線程? 我所做的以下嘗試很可能是有缺陷的,並且錯誤處理絕不是完整的。 但不知何故,我總是在這條線上出錯 -
pool.invokeAll
錯誤是 -
The method invokeAll(Collection<? extends Callable<T>>, long, TimeUnit) in the type ExecutorService is not applicable for the arguments (List<ModelFramework.ProcessBundleHolderEntry>, int, TimeUnit)
下面是我的方法,它將以多線程方式調用所有包的process method
。
public void processEvents(final Map<String, Object> eventData) {
ExecutorService pool = Executors.newFixedThreadPool(5);
List<ProcessBundleHolderEntry> entries = new ArrayList<ProcessBundleHolderEntry>();
Map<String, String> outputs = (Map<String, String>)eventData.get(BConstants.EVENT_HOLDER);
for (BundleRegistration.BundlesHolderEntry entry : BundleRegistration.getInstance()) {
ProcessBundleHolderEntry processBundleHolderEntry = new ProcessBundleHolderEntry(entry, outputs);
entries.add(processBundleHolderEntry);
}
try {
// somehow I always get an error at invokeAll method. Is there anything wrong?
List<Future<Object>> futures = pool.invokeAll(entries, 30, TimeUnit.SECONDS);
for (int i = 0; i < futures.size(); i++) {
// This works since the list of future objects are in the
// same sequential order as the list of entries
Future<Object> future = futures.get(i);
ProcessBundleHolderEntry entry = entries.get(i);
if (!future.isDone()) {
// log error for this entry
}
}
} catch (InterruptedException e) {
// handle this exception!
}
}
其次,我已經在ModelFramework類中添加了一個Callable實現
public class ProcessBundleHolderEntry implements Callable {
private BundleRegistration.BundlesHolderEntry entry;
private Map<String, String> outputs;
public ProcessBundleHolderEntry(BundleRegistration.BundlesHolderEntry entry, Map<String, String> outputs) {
this.entry = entry;
this.outputs = outputs;
}
public Object call() throws Exception {
final Map<String, String> response = entry.getPlugin().process(outputs);
// write to the database.
System.out.println(response);
return response;
}
}
任何人都可以幫我解決我得到的錯誤嗎? 還有人可以告訴我上述方法是否有任何問題,或者是否有更好,更有效的方法做同樣的事情?
任何幫助將不勝感激。
沒關系,我發現了實際的問題
public class ProcessBundleHolderEntry implements Callable {
應定義為
public class ProcessBundleHolderEntry implements Callable<Object> {
以便在以下聲明中匹配Object
類型
List<Future<Object>> futures = pool.invokeAll(entries, 30, TimeUnit.SECONDS);
invokeAll方法的簽名是
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
我所做的以下嘗試很可能是有缺陷的,並且錯誤處理絕不是完整的。 但不知何故,我總是在這條線上出錯 -
我認為問題是如果你想讓invokeAll(...)
返回List<Future<Object>>
, ProcessBundleHolderEntry
應該實現Callable<Object>
。 我剛剛編譯了你的代碼,這解決了這個問題。
在我看來它應該實現Callable<Map<String, String>>
。 然后call方法應該返回正確的類型:
public Map<String, String> call() throws Exception {
然后invokeAll(...)
方法將返回正確的List<Future<Map<String, String>>
。
一個不同的(盡管有點奇怪)想法是將this
從call()
方法中返回。 有ProcessBundleHolderEntry implements Callable<ProcessBundleHolderEntry>
並在返回之前記錄條目的響應this
從call()
。 然后你不需要在條目上get(i)
來匹配它。 然后在一個對象中有條目,輸出和響應。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.