它跟普通的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);
}
}