[英]Java Executor Service for parallel processing
在支持並行多個數據庫查詢的系統上工作。 考慮到每個數據庫都有很多數據要查詢,因此要求將每個數據庫查詢與其他數據庫分開。 這意味着,一個數據庫/表上的負載不應影響其他表查詢。 我使用ExecutorService開發了Java解決方案。 每個數據庫使用一個ExecutorService(具有1個線程的固定大小)。 我維護一個數據庫名稱TO ExecutorService的映射,並在接收查詢請求時將調用定向到相應的執行程序服務。 考慮到可以並行查詢一百個數據庫,不確定ExecutorService是否是正確的選擇...! 我已經進行了一些評估,初步結果還不錯。 該解決方案面臨的一個挑戰是,當我動態創建ExecutorServices時,要在應用程序停止時優雅地關閉它們變得越來越困難。
解決此問題的其他方法是維護查詢工作線程的全局(在所有數據庫中)池,並將其隨機用於傳入請求。 但是,這不能保證所有數據庫查詢都具有相同的優先級。
數據集工廠
public class DataSetExecutorFactory {
private static Map<String, DataSetExecutor> executorMap = Collections.synchronizedMap(new HashMap<String, DataSetExecutor>());
public static DataSetExecutor getDataSetExecutor(String dbName){
DataSetExecutor executor = null;
executor = executorMap.get(dbName);
if(executor == null){
executor = new DataSetExecutor(dbName);
executorMap.put(dbName, executor);
}
return executor;
}
}
}
DataSetExecutor.java
public class DataSetExecutor {
private ExecutorService executor = Executors.newFixedThreadPool(1);
public List<Map<String, Object>> execQuery(String collecName, Map<String, Object> queryParams){
//Construct Query job.
//QueryWorker extends 'Callable' and does the actual query to DB
QueryWorker queryWorker = new QueryWorker(Map queryParams);
Future<QueryResult> result = null;
try{
result = executor.submit(queryWorker);
}catch (Exception e){
//Catch Exception here
e.printStackTrace();
}
}
我認為您對ExecutorService的工作方式有誤解。 而不是為每個數據庫創建一個ExecutorService,您應該將單個ExecutorService作為大小為n(n =數據庫數或最大並行查詢數)的FixedThreadPool。 線程池將為您執行並行處理工作。 您只需要跟蹤數據庫名稱,並將其作為將提交到ExecutorService的QueryWorker的一部分。
這也使關閉變得容易,因為ThreadPool將自動清理未使用的線程,並且您只需要在應用程序關閉時將其關閉一次。
盡管如此,由於所有並行處理都是在同一JVM和同一台計算機上進行的,因此您可能會遇到內存或CPU限制,這取決於查詢的強度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.