First submit all your Actions to your thread pool in one loop - collecting the Future elements in a list or array. And call the Future.get() in a separate loop.
final MultiTaskStatus sharedStatus = new MultiTaskStatus(); final List<Future<Void>> pendingsResults = new ArrayList<Future<Void>>(threads); // submit all the jobs to be executed by the thread pool (executor) for (int i = 0; i < threads; i++) { // avoid submitting more tasks, if one already failed if (sharedStatus.isFailed()) { break; } final ReaderDirectWithPartition_JDBC job; // hand over the MultiTaskStatus to be set as failed on error job = new ReaderDirectWithPartition_JDBC(outputPath + i, partitionedQuery, propparameters, props, sharedStatus); pendingResults.add(executor.submit(job)); } if (sharedStatus.isFailed()) { // maybe do something special, if we already know something went wrong? } try { // wait for all scheduled jobs to be done for (final Future<Void> pendingJob : pendingResults) { pendingJob.get(); } } catch (final CancellationException ce) { log.error(ce.getMessage()); } catch (final ExecutionException ee) { log.error(ee.getMessage()); } catch (final InterruptedException ie) { log.error(ie.getMessage()); } finally { executor.shutdownNow(); }
with the separate state indicator
class MultiTaskStatus { private boolean failed = false; public synchronized void setFailed(boolean taskFailed) { this.failed = this.failed || taskFailed; } public synchronized boolean isFailed() { return this.failed; } }
Maybe consider using a CompletionService as mentioned in this answer.