使其漂亮:同时处理数组

its*_*dok 3 java concurrency multithreading

我想将这个线性循环转换为并发循环:

for(Item item : ItemList) {
    processItem(item);
}
Run Code Online (Sandbox Code Playgroud)

这真的是最短的方式吗?

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();
}
Run Code Online (Sandbox Code Playgroud)

具体来说,我想要一种使用匿名类的方法,但实际上,任何使这种更短和更易读的方法都会受到赞赏.

更新:刚刚意识到我有点愚蠢,因为在这个例子中使用匿名类很容易:

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

在我的原始代码中,循环很简单for (i=0; i<=ItemList.length(); i++),我无法想出以任何有意义的方式使我最终的方法.我想使用"for each"循环可以使情况更好.

还有什么方法可以摆脱其余的样板?

更新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();
}
Run Code Online (Sandbox Code Playgroud)

这确实看起来更好.

Gan*_*alf 7

查看JDK 6中的ExecutorCompletionService - 而不是旋转自己的.它允许您为分配的任务执行多个线程,并在处理时获取每个线程的结果.

  • ExecutorCompletionService也在JDK5中. (3认同)