Do this: processing the array at the same time

I want to convert this linear loop to parallel:

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();
}

In particular, I would like to use an anonymous class, but really, any way to make it shorter and more readable would be appreciated.

UPDATE: I just realized that I'm a little stupid, because in this example it is quite easy to use an anonymous class:

for(final Item item : ItemList) {
    exec.execute(new Runnable() {
        public void run() {
            processItem(item);
        }
    });
}

In my source code, the loop was simple for (i=0; i<=ItemList.length(); i++), and I could not figure out how to make final in any sense, which makes sense. I assume that using the "for everyone" loop will improve the situation.

However, any way to get rid of the rest of the template?

2. ExecutorCompletionService, , processItem .

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();
}

.

+3
2

ExecutorCompletionService JDK 6, . .

+7

, , , , :

List<Future<ResultType>> futures = new ArrayList<Future<ResultType>>();
for(final Item item : items) {
  futures.add(executor.submit(...))
}
List<ResultType> results = new ArrayList<ResultType>();
for(Future<ResultType> future : futures) {
  results.add(future.get());
}
return results;

EDIT: , ( , ):

return Iterators.transform(results, new Function<Future<ResultType>,ResultType>() {
   public ResultType apply(Future<ResultType> future) {
       return future.get();
   }
})

"" google. , .

+1

Source: https://habr.com/ru/post/1709165/


All Articles