十、Callable与Future

Callable返回结果并且可能抛出异常的任务。实现者定义了一个不带任何参数的叫做 call 的方法。

Callable接口类似于Runnable。

示例一:

Runnable接口示例:

new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+": hello");
            }
        }).start();

Callable接口示例:

Callable<String> callable = new Callable<String>() {   //这里的泛型与你想要的返回结果(call方法的返回值)一致
      @Override
      public String call() throws Exception {  //可以抛异常
           return Thread.currentThread().getName()+"hello";
      }
};
FutureTask<String> futureTask = new FutureTask<String>(callable);  //这里的泛型与Callable中泛型类型一致,也就是call()返回值类型一致。
new Thread(futureTask).start(); //FutureTask实现了Runnable接口和Future接口,Future用来接收返回值。
System.out.println(futureTask.get());  //获取返回结果

Runnable 接口 与 Callable 接口的区别 :任务调用的方法分别是run()和call(),run()没有返回值,也没有定义异常(所以不能抛异常),而call()方法有返回值,而且可以抛异常。

使用线程池来执行Callable任务:

示例二:

public class CallableTest {
     public static void main(String[] args) throws Exception {
        //创建一个单线程的线程池
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        //这里不再使用execute(Runnable runnable)方法,而是使用submit(Callable<String> task),用法与Runnable类似,只是有返回值,用Future接口来接收返回值。
        Future<String> future = executorService.submit(new Callable<String>(){
            @Override
            public String call() throws Exception {
                return "hello";
            }
        });
        System.out.println("拿到结果:"+future.get());  //得到方法执行的返回结果    

     }
}


示例三:

 与上面的类似,只不过下面的执行的多个任务,上面的执行的是单个任务。

public class CallableAndFutureTest {
    
    /**
     * 
     * @Description 在线程池里面执行Callable任务
     * @author fulaizhi
     * @date 2016年6月18日 下午2:37:19
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {

        ExecutorService executorService2 = Executors.newCachedThreadPool();
        CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(executorService2);
        for (int i = 1; i <= 10; i++) {
            final int temp = i;
            completionService.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    Thread.sleep(new Random().nextInt(5000));
                    return temp;
                }
            });
        }
        for(int i = 0; i<10;i++){
            /**
             * 返回最先先执行完成的结果,如果都没有执行完成,就等待第一个完成任务的结果返回
             * 然后下次调用则等待新的返回结果,直到结果返回。如果没有结果返回,则会一直等待到下去。
             */
            Future<Integer> future = completionService.take();  
            System.out.println(future.get()); 
        }
    }
}
原文地址:https://www.cnblogs.com/futiansu/p/5616366.html