多线程-从Future对象中获取线程处理Callable方法的结果

来源:互联网 发布:连环夺宝编程原理 编辑:程序博客网 时间:2024/06/01 09:01

Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为 run 的无参数方法。


以上为Runnable接口的描述,明确可以看出,实现Runnable子类的实例是被线程来运行的。但是看看run方法的定义为void,因此,获取run方法中的处理结果比较麻烦,这时候jdk1.5提供了解决办法。1.5之后提供了

java.util.concurrent

包,该包下面有个callable<V>接口,该接口是泛型接口,泛型类型就是你的返回值类型,下面是接口定义。


public interface Callable<V> {    /**     * Computes a result, or throws an exception if unable to do so.     *     * @return computed result     * @throws Exception if unable to compute a result     */    V call() throws Exception;}


可以看到和Runnable最大的区别就是由返回值类型。这个接口可以说完全是和Runnable一样的,区别是一个是有返回值一个是无返回值。

下面我们来实现它。

public class MyCall implements Callable<String> {    @Override    public String call() throws Exception {        System.out.println("=========");        return "return value 123";    }}

但是想想就算我们可以有返回值了,但是要如何获取这个返回值呢,也就是我们要在哪里 get()返回值呢?

Thread类中肯定是没有的,而且,如果我们new Thread类会发现没有构造函数参数为Callable<V>,这就比较尴尬了。

所以,如果让我们自己来做的话,那唯一的办法可能就是让某个类,实现Runable方法,然后这个实现类的run方法中调用callable,然后获取返回值。

实际上,Future就是这么做的,Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。

Future本身是个接口,因为我们需要用到它的实现类 FutureTask<V>


public class FutureTask<V> implements RunnableFuture<V>


public interface RunnableFuture<V> extends Runnable, Future<V>

以上类继承结构可以看出,FutureTask同时继承了Runable以及Future,也就意味着,FutureTask可以被线程运行,同时也可以获取到线程运行后的计算结果。

然后看FutureTask的构造函数。




以上构造函数很明显,FutureTask既可以获取线程的计算结果也可以不需要返回结果。

到这里我想我们可以自己来编写测试代码了。


FutureTask<String> future = new FutureTask<String>(new MyCall());        Thread thread = new Thread(future);        thread.start();        System.out.println(future.get());        System.out.println(future.get());


输出:

=========
return value 123
return value 123


至于为什么只输出一遍=====,这就是我们之前说的,Future调用了Callable并且获取记录了返回值,而call方法他其实只走了一遍。


最后一图流。



参考资料

http://blog.csdn.net/ghsau/article/details/7451464



阅读全文
0 0
原创粉丝点击