021 Callable接口

一 .概述

  在前面,我们创建线程总是需要实现run()方法,无论继承还是实现run()方法.

  我们首先看一下run()方法的结构.  

 public  void run();

  我们首先看到的是run()方法没有返回值,没有异常声明.

  这也就决定我们使用run()方法会有一点麻烦的地方.

  [1]返回值我们需要特殊处理

  [2]异常的问题有些麻烦,尽管我们可以使用UncaughtExceptionHandler来处理.


二 .问题的解决

  从JDK1.5之后出现了Callable接口,可以解决上面的麻烦.

  我们首先观看一下该接口的定义:  

@FunctionalInterface
public interface Callable<V> {

    V call() throws Exception;
}

我们发现该接口有了返回值,还有了异常的声明.


三 .Callable接口的使用  

public class CallableTest {
    
    static class Caller implements Callable<Integer>{

        @Override
        public Integer call() throws Exception {
            int count = 0 ;
            TimeUnit.SECONDS.sleep(3);
            for(int x = 0;x<100;x++) {
                count ++;
            }
            return count;
        }
    }
    
    public static void main(String[] args) throws Exception {
        //创建线程池
        ExecutorService ex = Executors.newCachedThreadPool();
        Future<Integer> future = ex.submit(new Caller());
        ex.shutdown();
        System.out.println("获取结果count:" + future.get());
        System.out.println("结果获取完毕");
    }
}

  上面的例子演示了Callable接口的使用,本质上讲和Runnable中的run()方法的使用时一致的,一般情况下都是配合线程池的使用.

  线程池的使用在这里不做多说了.

  我们可以看到一旦提交了线程任务之后就可以获得一个Futrure对象,这个对象包含返回值对象.

  也就是说我们可以通过这个对象获取到返回值,这个故意多加了最后一句,我们方法上述代码在执行的过程之中等待了一会,说明Future的get()方法是阻塞式的.

  下面一节,说一下Future的内容.

原文地址:https://www.cnblogs.com/trekxu/p/9005173.html