多线程--callable、Future、FutureTask

除了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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值