例示CompletionService的使用

它跟普通的Executor + Callable + Future 没什么本质区别。只不过当有多个任务需要提交时,自己手动维护一堆Future、并依次地调用future.get() 会很繁琐。 CompletionService使这个变得简单很多。

package player.kent.chen.learn.completionservice;

import java.io.File;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.apache.commons.io.FileUtils;

public class HelloCompletionService {

    public static void main(String[] args) throws InterruptedException {
        //生成CompletionService实例
        ExecutorService executor = Executors.newFixedThreadPool(2);
        CompletionService<String> completionService = new ExecutorCompletionService<String>(
                executor);

        //定义任务并置入CompletionService任务池
        for (int i = 0; i < 4; i++) {
            final String fn = String.valueOf(i) + ".txt";
            Callable<String> task = new Callable<String>() {
                public String call() throws Exception {
                    return FileUtils.readFileToString(new File("/home/kent/temp/" + fn));
                }
            };
            completionService.submit(task);
        }

        for (int i = 0; i < 4; i++) {
            Future<String> future = null;
            try {
                //至少有一个任务完成了,take()才能拿到东西; 所以这里的future其实是done==true的future
                //这也正是CompletionService的作用:任务一旦完成,就可以被取到
                future = completionService.take();
                String text = future.get();
                System.out.println(text);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                future.cancel(true);
                return;
            } catch (ExecutionException e) {
                e.printStackTrace(); //真正的应用中应该注意一下此处的处理
            }
        }

        executor.shutdown();
        executor.awaitTermination(1000l, TimeUnit.SECONDS);

    }
}

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.