/* This is different from threadly's FutureUtils because * we want logging progress as futures complete...Since * these futures may take a VERY long time to complete. * The alternative would be to add runnables to these * so that we log out at 10% intervals, but that would assume * that the futures complete mostly in order. */ public static void blockTillAllDone(List<Future<?>> futures) { float doneCount = 0; int lastReportedDonePercent = 0; Iterator<Future<?>> it = futures.iterator(); while (it.hasNext()) { try { Future<?> f = it.next(); if (!f.isDone() || !it.hasNext()) { // we take * 10 and / 10 so we can get one additional decimal of accuracy int donePercent = (int) Math.round((doneCount / futures.size()) * 100 * 10); if (donePercent != lastReportedDonePercent) { lastReportedDonePercent = donePercent; System.out.println("Progress: " + (donePercent / 10.) + "%"); } f.get(); } doneCount++; } catch (InterruptedException e) { ExceptionUtils.handleException(e); return; // let thread exit } catch (ExecutionException e) { ExceptionUtils.handleException(e); } } }
/** * Internal tick implementation. Allowing control on if the cancelTick boolean should be reset if * no tasks are run. Thus allowing for an optimistic attempt to run tasks, while maintaining the * cancelTick state. * * @param exceptionHandler Exception handler implementation to call if any tasks throw an * exception, or null to have exceptions thrown out of this call * @param resetCancelTickIfNoTasksRan if {@code true} will reset cancelTick weather tasks ran or * not, otherwise cancelTick will only be reset if tasks ran * @return quantity of tasks run during this tick invocation */ private int tick( ExceptionHandlerInterface exceptionHandler, boolean resetCancelTickIfNoTasksRan) { int tasks = 0; TaskContainer nextTask; while ((nextTask = getNextTask(true)) != null && !tickCanceled) { // call will remove task from queue, or reposition as necessary try { nextTask.runTask(); } catch (Throwable t) { if (exceptionHandler != null) { exceptionHandler.handleException(t); } else { throw ExceptionUtils.makeRuntime(t); } } tasks++; } if ((tasks != 0 || resetCancelTickIfNoTasksRan) && tickCanceled) { // reset for future tick calls tickCanceled = false; } return tasks; }
@Override public void run() { while (!stopped) { try { T next = getNext(); acceptor.acceptConsumedItem(next); } catch (InterruptedException e) { stop(); } catch (Throwable t) { ExceptionUtils.handleException(t); } } }