Source:
public void perform(final GraphRewrite event, final EvaluationContext context) { Iterable<? extends WindupVertexFrame> reportModelsIterable = Variables.instance(event) .findVariable(Iteration.DEFAULT_VARIABLE_LIST_STRING); final Queue<WindupVertexFrame> reportModels = new LinkedList<>(); for (WindupVertexFrame frame : reportModelsIterable) reportModels.add(frame); final FreeMarkerIterationOperation freeMarkerIterationOperation = FreeMarkerIterationOperation.create(furnace); final IterationProgress iterationProgress = IterationProgress.monitoring("Rendering Reports", 100); int threadCount = WindupExecutors.getDefaultThreadCount(); ExecutorService executorService = WindupExecutors.newFixedThreadPool(WindupExecutors.getDefaultThreadCount()); event.getRewriteContext().put(Iteration.DEFAULT_VARIABLE_LIST_STRING, reportModels); iterationProgress.perform(event, context); for (int i = 0; i < threadCount; i++) { executorService.submit(new Callable<Void>() { @Override public Void call() throws Exception { while (true) { final ReportModel reportModel; synchronized (reportModels) { WindupVertexFrame reportModelObject = reportModels.remove(); if (reportModelObject == null) return null; reportModel = (ReportModel) reportModelObject; } Thread.currentThread().setName(reportModel.getTemplatePath() + "_" + reportModel.getReportFilename()); iterationProgress.perform(event, context); freeMarkerIterationOperation.perform(event, context, reportModel); } } }); } executorService.shutdown(); try { executorService.awaitTermination(2, TimeUnit.DAYS); } catch (InterruptedException e) { throw new WindupException("Failed to render reports due to a timeout: " + e.getMessage(), e); } event.getRewriteContext().put(Iteration.DEFAULT_VARIABLE_LIST_STRING, null); }

Target:
public void perform(final GraphRewrite event, final EvaluationContext context) { Iterable<? extends WindupVertexFrame> reportModelsIterable = Variables.instance(event) .findVariable(Iteration.DEFAULT_VARIABLE_LIST_STRING); final Queue<WindupVertexFrame> reportModels = new ConcurrentLinkedDeque<>(); for (WindupVertexFrame frame : reportModelsIterable) reportModels.add(frame); final FreeMarkerIterationOperation freeMarkerIterationOperation = FreeMarkerIterationOperation.create(furnace); final IterationProgress iterationProgress = IterationProgress.monitoring("Rendering Reports", 100); int threadCount = WindupExecutors.getDefaultThreadCount(); ExecutorService executorService = WindupExecutors.newFixedThreadPool(WindupExecutors.getDefaultThreadCount()); event.getRewriteContext().put(Iteration.DEFAULT_VARIABLE_LIST_STRING, reportModels); iterationProgress.perform(event, context); for (int i = 0; i < threadCount; i++) { executorService.submit(new Callable<Void>() { @Override public Void call() throws Exception { while (true) { final ReportModel reportModel; WindupVertexFrame reportModelObject = reportModels.remove(); if (reportModelObject == null) return null; reportModel = (ReportModel) reportModelObject; Thread.currentThread().setName(reportModel.getTemplatePath() + "_" + reportModel.getReportFilename()); iterationProgress.perform(event, context); freeMarkerIterationOperation.perform(event, context, reportModel); } } }); } executorService.shutdown(); try { executorService.awaitTermination(2, TimeUnit.DAYS); } catch (InterruptedException e) { throw new WindupException("Failed to render reports due to a timeout: " + e.getMessage(), e); } event.getRewriteContext().put(Iteration.DEFAULT_VARIABLE_LIST_STRING, null); }