I want to convert this linear loop into a concurrent one:
for(Item item : ItemList) {
processItem(item);
}
Is this really the shortest way to do this?
class Worker implements Runnable {
Item item;
Worker(Item item) {
this.item = item;
}
public void Run() {
processItem(item);
}
}
ExecutorService exec = Executors.newFixedThreadPool(THREADPOOL_SIZE);
for(Item item : ItemList) {
exec.execute(new Worker(item));
}
exec.shutdown();
boolean properFinish = false;
try {
properFinish = exec.awaitTermination(50, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
Specifically, I would like a way to use an anonymous class, but really, any way to make this shorter and more readable would be appreciated.
UPDATE: Just realized I was being a bit stupid, since it's pretty easy to use an anonymous class in this example:
for(final Item item : ItemList) {
exec.execute(new Runnable() {
public void run() {
processItem(item);
}
});
}
In my original code, the loop was a simple for (i=0; i<=ItemList.length(); i++)
and I couldn't think of a way to make i final in any way that makes sense. I guess using a "for each" loop make the situation better.
Still, any way to get rid of the rest of the boilerplate?
UPDATE 2: Using ExecutorCompletionService
, assuming processItem
returns a result.
ExecutorService exec = Executors.newFixedThreadPool(THREADPOOL_SIZE);
CompletionService<ResultType> ecs = new ExecutorCompletionService<ResultType>(executor);
for(final Item item : ItemList) {
ecs.submit(new Callable<ResultType>() {
public ResultType call() {
return processItem(item);
}
});
}
for(Item item : item) {
// Do whatever with the results
ecs.take().get();
}
This does look nicer.