/** * Execute the {@link Callable} tasks in parallel (per the configured size of the {@link * WorkerPool}) and wait for them to complete. * * @param tasks a map of {@link Callable}s with keys by which you will be able to access each * return value * @return the return values of each {@link Callable}s mapped by their input key */ public <K, V> Map<K, V> invokeAll(Map<K, Callable<V>> tasks) { String caller = LOGGER.isDebugEnabled() ? Thread.currentThread().getStackTrace()[2].toString() : "n/a"; LOGGER.debug("[%s] is invoking %d mapped tasks", caller, tasks.size()); List<K> orderedKeys = new ArrayList<K>(tasks.size()); List<Callable<V>> orderedTasks = new ArrayList<Callable<V>>(tasks.size()); for (Map.Entry<K, Callable<V>> entry : tasks.entrySet()) { orderedKeys.add(entry.getKey()); orderedTasks.add(entry.getValue()); } try { long start = System.currentTimeMillis(); List<Future<V>> executorResults = executorService.invokeAll(orderedTasks); long finish = System.currentTimeMillis(); LOGGER.debug("[%s] invoked %d mapped tasks in %d ms", caller, tasks.size(), finish - start); Map<K, V> mappedResults = new LinkedHashMap<K, V>(tasks.size()); for (int i = 0; i < tasks.size(); i++) { K key = orderedKeys.get(i); V result = executorResults.get(i).get(); mappedResults.put(key, result); } return mappedResults; } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); } }
/** * Execute the {@link Callable} tasks in parallel (per the configured size of the {@link * WorkerPool}) and wait for them to complete. * * @param tasks a list of {@link Callable}s * @return the ordered return values */ public <T> List<T> invokeAll(List<Callable<T>> tasks) { String caller = LOGGER.isDebugEnabled() ? Thread.currentThread().getStackTrace()[2].toString() : "n/a"; LOGGER.debug("[%s] is invoking %d listed tasks", caller, tasks.size()); try { long start = System.currentTimeMillis(); List<Future<T>> executorResults = executorService.invokeAll(tasks); long finish = System.currentTimeMillis(); LOGGER.debug("[%s] invoked %d listed tasks in %d ms", caller, tasks.size(), finish - start); List<T> results = new ArrayList<T>(tasks.size()); for (Future<T> future : executorResults) { results.add(future.get()); } return results; } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); } }
/** * Create a pool with the specified number of threads. * * @param nThreads */ public WorkerPool(int nThreads) { LOGGER.debug("initializing worker pool with %d threads", nThreads); executorService = LOGGER.isDebugEnabled() ? new MetricReportingExecutorService(LOGGER, nThreads) : Executors.newFixedThreadPool(nThreads); Runtime.getRuntime() .addShutdownHook( new Thread() { @Override public void run() { shutdownAndAwaitTermination(10); } }); }