Java并发Concurrent包——Callable/Future/FutureTask解析

Runnable 接口,由于是 void 方法,是没有返回结果的,在并发包中,有 Callable 类,能够得到执行的结果。

Callable

返回结果并且可能抛出异常的任务。实现者定义了一个不带任何参数的叫做 call 的方法。
Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。

public interface Callable<V> {
    // 计算结果,如果无法计算结果,则抛出一个异常
    V call() throws Exception;
}

Callable一般是和ExecutorService配合来使用的。

Future

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

public interface Future<V> {
    // 试图取消对此任务的执行
    boolean cancel(boolean mayInterruptIfRunning);
    // 如果在任务正常完成前将其取消,则返回true
    boolean isCancelled();
    // 如果任务已完成,则返回true
    boolean isDone();
    // 如有必要,等待计算完成,然后获取其结果
    V get() throws InterruptedException, ExecutionException;
    // 如有必要,最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

RunnableFuture

作为 Runnable 的 Future。成功执行 run 方法可以完成 Future 并允许访问其结果。

public interface RunnableFuture<V> extends Runnable, Future<V> {
    // 在未被取消的情况下,将此Future设置为计算的结果
    void run();
}

FutureTask

实现 RunnableFuture 接口,既可以作为 Runnable 被执行,也可以作为 Future 得到 Callable 的返回值。
从下边构造函数可以看出,可以接受 Callable 或 Runnable 来创建 FutrueTask 。

    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 class TestExecutor {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        System.out.println("主线程执行");
        ExecutorService executor = Executors.newCachedThreadPool();
        Future<Integer> result = executor.submit(new CountTask());
        executor.shutdown();
        Integer i = result.get();
        System.out.println("主线程结束");
        System.out.println("主线程获取子线程结果为:" + i);

    }

    public static class CountTask implements Callable<Integer>{

        @Override
        public Integer call() throws Exception {
            System.out.println("子线程开始计算");
            Thread.sleep(5000);
            System.out.println("子线程结束计算,共用时5秒");
            return 100;
        }

    }

}

运行结果为:

主线程执行
子线程开始计算
子线程结束计算,共用时5秒
主线程结束
结果为:100

在例子中,如果要使用 FutureTask ,应这样:

ExecutorService executor = Executors.newCachedThreadPool();
        // Future的使用
        //Future<Integer> result = executor.submit(new CountTask());

        // FutureTask的使用
        FutureTask<Integer> futureTask = new FutureTask<>(new CountTask());
        executor.submit(futureTask);

        executor.shutdown();
        // Future获取结果
        //Integer i = result.get();
        // futureTask获取结果
        Integer i = futureTask.get();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值