import java.util.ArrayList; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; public class SimpleExecutorCompletionService { private ExecutorService ex; private ArrayList> pendingFutures; private ArrayList> doneFutures; public SimpleExecutorCompletionService(ExecutorService ex) { this.ex = ex; this.pendingFutures = new ArrayList<>(); this.doneFutures = new ArrayList<>(); } synchronized public Future submit(Callable task) { Future f = ex.submit(task); this.pendingFutures.add(f); return f; } synchronized public Future poll() { this.updateFuturesLists(); if (!this.doneFutures.isEmpty()) { return this.doneFutures.removeLast(); } else { return null; } } synchronized private void updateFuturesLists() { for (int i = 0; i < this.pendingFutures.size(); i++) { Future f = this.pendingFutures.get(i); // for (Future f : this.pendingFutures) { // causes concurrent access exception - why? if (f.isDone()) { this.pendingFutures.remove(f); this.doneFutures.add(f); } } } }