多线程--callable、Future、FutureTask

来源:互联网 发布:丹尼斯约翰逊数据 编辑:程序博客网 时间:2024/06/10 22:20
除了Runnable外,JAVA中还有callable、Future、FutureTask这几个线程。与Runnable不同的是,他们只能运用到线程池中,而Runnable可以使用到Thread中。

一、Callable
他和Runnable功能大致相同,不同的是他有一个返回值。
他的声明如下:

public interface Callable<V> {//返回V类型的结果V call() throws Exception{}}

二、Future
Runnable和Callable都无法对线程进行控制,一旦开始就无法进行管理。而Future可以执行cancel、isDone、get、set等方法。具体声明如下:

public interface Future<V> {//取消线程boolean cancel(boolean mayInterruptIfRunning);//是否已经取消boolean isCancelled;//是否已经完成boolean isDone();//获取结果,若未完成则阻塞直到任务完成V get() throws InterruptedException,ExecutionException;//获取结果,若未完成则阻塞直到任务完成、或者超时。unit为时间单位V get(long Timeout , TimeUnit unit) throws InterruptedException,ExecutionException,timeoutException;}

get方法会阻塞直到任务完成,返回结果
三、FutureTask
它是Future接口的实现类,同时还实现了Runnable接口。

public class FutureTask<V> implements RunnableFuture<V> {public FutureTask(Callable<V> callable) {    if (callable == null)        throw new NullPointerException();    this.callable = callable;    this.state = NEW;       // ensure visibility of callable}public FutureTask(Runnable runnable, V result) {    this.callable = Executors.callable(runnable, result);    this.state = NEW;       // ensure visibility of callable}}public interface RunnableFuture<V> extends Runnable, Future<V> {    void run();}

可以看见FutureTask实现了 RunnableFuture,而 RunnableFuture继承了Runnable, Future;其中callable和Runnable通过构造函数注入,不过通过代码,我们可以知道注入的Runnable最后也转换为callable类型的任务。
由此可见,FutureTask实现了Runnable接口,可以通过Thread来直接运行,也可以提交到线程池,同时还能通get拿到结果。
现在通过一个DEMO来直观的展示他们之间的区别。

public class mFutureDemo {    //线程池    static ExecutorService mExecutor = Executors.newSingleThreadExecutor();    //主程序    public static void main(){    }    private static void runnable() throws ExecutionException, InterruptedException {        Future<?> result = mExecutor.submit(new Runnable() {            @Override            public void run() {                fibc(20);            }        });        System.out.print("runnable"+result.get());    }    private static void callable() throws ExecutionException, InterruptedException {        Future<Integer> result = mExecutor.submit(new Callable<Integer>() {            @Override            public Integer call() throws Exception {                return fibc(20);            }        });        System.out.print("callable"+result.get());    }    private static void futureTask() throws ExecutionException, InterruptedException {        FutureTask<Integer> task=new FutureTask<Integer>(new Callable<Integer>() {            @Override            public Integer call() throws Exception {                return fibc(20);            }        });        mExecutor.submit(task);        //也可以和Runnable一样交给Thread来处理。        //Thread thread=new Thread(task);        //thread.start();        System.out.print("futureTask"+task.get());    }    //耗时操作    private static int fibc(int num){        if (num==0) return 0;        if (num==1) return 1;        return fibc(num-1)+fibc(num-2);    }}

输出结果为:
runnable null;
callable 6765;
futureTask 6765;

上诉为非常简单的DEMO没有过多的注释,从中我们可以看出:
1、runnable是没有返回值的,callable和futureTask有返回值
2、runnable,callable是通过线程池返回的future来进行管理,无法自行管理;
而futureTask可以自行get返回值
3、其中get方法会阻塞,直到结果出来,才执行的打印语句。

0 0
原创粉丝点击