簡體   English   中英

ExecutorService類型中的方法invokeAll不適用於參數錯誤

[英]Method invokeAll in the type ExecutorService is not applicable for the arguments error

我正在開展一個項目,我將在其中使用不同的Bundles。 讓我們舉個例子,假設我有5個Bundle,每個bundle都有一個方法名稱process

以下是我應該做的事情 -

  1. 我需要使用多線程代碼並行調用所有這5個Bundles process方法,然后寫入數據庫。 我不確定這樣做的正確方法是什么? 我應該有五個帖嗎? 每個捆綁一個線程? 但是在那種情況下會發生什么,假設我有50個捆綁,那么我將有50個線程?
  2. 而且,我也希望有超時功能。 如果任何捆綁包花費的時間超過我們設置的閾值,那么它應該超時並記錄為該捆綁包花費了大量時間的錯誤。

我所做的以下嘗試很可能是有缺陷的,並且錯誤處理絕不是完整的。 但不知何故,我總是在這條線上出錯 -

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

一個不同的(盡管有點奇怪)想法是將thiscall()方法中返回。 ProcessBundleHolderEntry implements Callable<ProcessBundleHolderEntry>並在返回之前記錄條目的響應thiscall() 然后你不需要在條目上get(i)來匹配它。 然后在一個對象中有條目,輸出和響應。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM