簡體   English   中英

線程安全問題,同時使每個捆綁包的線程超時

[英]Thread safety issue while timing out the thread for each bundle

我正在一個項目中,我將具有不同的包/模型。 讓我們舉個例子,假設我有4個捆綁包,每個捆綁包都有一個方法名process

以下是我應該做的事情-

  1. 我需要使用多線程並行調用所有這4個Bundles process method ,並且每個bundle中的process method將返回一個映射,然后將該映射寫入同一線程中或執行最佳方法的數據庫中(我不確定在這是正確的方法)。
  2. 我也想在線程級別啟用某種超時功能。 這意味着如果某個Bundle需要花費很多時間來執行,那么Bundle線程應該超時並記錄一個錯誤,指出該特定的bundle超時了,因為花費了很多時間。

我所做的以下嘗試很可能是有缺陷的,錯誤處理絕不是完整的。 有人可以指導我在錯誤處理案例中應該做什么嗎?

下面是我的方法,它將以多線程方式調用所有捆綁包的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 {
        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!
    }
}

其次,為您的線程實現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;
    }
}

誰能告訴我上述方法是否有問題,或者有沒有更好,更有效的方法來做同樣的事情? 我不確定是否也存在線程安全問題。

任何幫助將不勝感激。

您代碼中唯一的共享對象是eventData :只要在運行此方法時未對其進行修改(或者如果地圖及其內容是線程安全的並且更改被安全地發布),則應該沒問題。

關於任務的異常處理,通常需要執行以下操作:

try {
    future.get();
} catch (ExecutionException e) {
    Throwable exceptionInFuture = e.getCause();
    //throw, log or whatever is appropriate
}

關於被中斷的異常:這意味着您正在其中執行該方法的線程已被中斷。 您需要執行的操作取決於您的用例,但通常應該停止正在執行的操作,例如:

} catch (InterruptedException e) {
    pool.shutdownNow(); //cancels the tasks
    //restore interrupted flag and exit
    Thread.currentThread.interrupt();
    //or rethrow the exception
    throw e;
}

注意:線程池的用途是可重用的-您應該將執行程序服務聲明為(私有最終)實例變量,而不是每次調用processEvents方法時都創建一個實例變量。

暫無
暫無

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

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