import java.util.concurrent.*; public class CallableDemo { public static void main(String[] args) throws ExecutionException, InterruptedException { //建立一个线程池 ExecutorService pool = Executors.newSingleThreadExecutor(); //建立有返回值的任务 Callable callable = new MyCallable("zhangsan"); //执行任务并获取Future对象 Future future = pool.submit(callable); //从Future对象上获取任务的返回值,并输出到控制台 System.out.println("等待结果..."); System.out.println("获得结果:"+future.get().toString()); //关闭线程池 pool.shutdown(); } } class MyCallable implements Callable{ private String name; MyCallable(String name) { this.name = name; } @Override public Object call() throws Exception { Thread.sleep(2000); return name + "返回的内容"; } }
CompletionService用于提交一组Callable任务,其take()方法返回已完成的一个Callable任务对应的Feture对象。 java
CompletionService采起的是BlockingQueue<Future<V>>无界队列来管理Future。则有一个线程执行完毕把返回结果放到BlockingQueue<Future<V>>里面。就能够经过completionServcie.take().get()取出结果,同时还有一个poll()方法,这两个方法的区别以下:import java.util.Random; 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; public class CompletionServiceDemo { public static void main(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(10); CompletionService<Integer> completionServcie = new ExecutorCompletionService<Integer>(pool); try { for (int i = 0; i < 10; i++) { completionServcie.submit(new MyCallable(i)); } for (int i = 0; i < 10; i++) { // take 方法等待下一个结果并返回 Future 对象。 // poll 不等待,有结果就返回一个 Future 对象,不然返回 null。 System.out.println(completionServcie.take().get()); } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } finally { pool.shutdown(); } } } class MyCallable implements Callable<Integer>{ private int i; Task(int i) { this.i = i; } @Override public Object call() throws Exception { Thread.sleep(new Random().nextInt(5000)); System.out.println(Thread.currentThread().getName() + " " + i); return i; } }