Callable和Future

发表时间:2017-10-18 09:14:54 浏览量( 27 ) 留言数( 0 )

学习目标:

1、了解Callable的作用

2、了解Future的作用

3、能在实践中灵活的使用Callable和Future


学习过程:

     前面我们使用join操作可以让我们知道线程执行完毕了,但是如果我们需要获得线程的返回值呢?那么我们就可以使用Callable和Future。

    Callable和Runnable非常类似,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值

    FutureTask实现了两个接口,Runnable和Future,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值,那么这个组合的使用有什么好处呢?假设有一个很耗时的返回值需要计算,并且这个返回值不是立刻需要的话,那么就可以使用这个组合,用另一个线程去计算返回值,而当前线程在使用这个返回值之前可以做其它的操作,等到需要这个返回值时,再通过Future得到。

示例代码如下:

public class CallableAndFuture {
    public static void main(String[] args) {
        Callable<Integer> callable = new Callable<Integer>() {
            public Integer call() throws Exception {
                return new Random().nextInt(100);
            }
        };
        FutureTask<Integer> future = new FutureTask<Integer>(callable);
        new Thread(future).start();
        try {
            Thread.sleep(5000);// 可以执行其他的操作
            System.out.println(future.get());//需要的时候获得线程的返回值,这个时候会阻塞,等待线程执行完毕,并获得线程的返回值
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


Future的原理:

   FutureTask是一个可取消的异步计算,FutureTask 实现了Future的基本方法,提供start cancel 操作,可以查询计算是否已经完成,并且可以获取计算的结果。结果只可以在计算完成之后获取,get方法会阻塞当计算没有完成的时候,一旦计算已经完成, 那么计算就不能再次启动或是取消。当然Future也有很多问题的,比如你不能知道线程是时候会执行完毕,程序会一直阻塞等等。