且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Future和Callable

更新时间:2022-01-18 22:00:34

Callable

Callable和Runnbale一样代表着任务,区别在于Callable有返回值并且可以抛出异常

Future

Future接口代表了线程池的异步计算结果。接口中的方法用来检查计算是否完成、等待完成和得到计算的结果。当计算完成后,只能通过get()方法得到结果,get方法会阻塞直到结果准备好了。如果想取消,那么调用cancel()方法。其他方法用于确定任务是正常完成还是取消了。一旦计算完成了,那么这个计算就不能被取消。

FutureTask类

FutureTask类实现了RunnableFuture接口,而RunnnableFuture接口继承了Runnable和Future接口,所以说FutureTask也是一个提供异步计算的结果的类。 FutureTask可以用来包装Callable或者Runnbale对象。因为FutureTask实现了Runnable接口,所以FutureTask也可以被提交给Executor。FutureTask既可以作为Runnable被执行,也可以作为Future得到Callable的返回值。

Future和Callable

Future作为异步计算的顶层接口,Future对具体的Runnable或者Callable任务提供了三种操作:执行任务的取消、查询任务是否完成、获取任务的执行结果。其接口定义如下:

public interface Future<V> {

    /**
     * 试图取消对此任务的执行
     * 如果任务已完成、或已取消,或者由于某些其他原因而无法取消,则此尝试将失败。
     * 当调用 cancel 时,如果调用成功,而此任务尚未启动,则此任务将永不运行。
     * 如果任务已经启动,则 mayInterruptIfRunning 参数确定是否应该以试图停止任务的方式来中断执行此任务的线程
     */
    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继承Future、Runnable两个接口,即所谓的Runnable的Future。提供了一个run()方法完成Future并允许访问其结果。

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

AbstractExecutorService提供了newTaskFor()方法返回一个RunnableFuture,除此之外当我们把一个Runnable或者Callable提交给(调用submit())ThreadPoolExecutor或者ScheduledThreadPoolExecutor时,他们则会向我们返回一个FutureTask对象,如下:

    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }
        protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }

    <T> Future<T> submit(Callable<T> task)
    <T> Future<T> submit(Runnable task, T result)
    Future<> submit(Runnable task)

ExecutorCompletionService

实现了CompletionService,将执行完成的任务放到阻塞队列中,通过take或poll方法来获得执行结果

/**
 * Created by xmr on 2018/8/28.
 * 启动10条线程,谁先执行完成就返回谁
 */
public class CompletionServiceTest {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //创建包含10条线程的线程池
        ExecutorService executor = Executors.newFixedThreadPool(10);
        CompletionService completionService = new ExecutorCompletionService(executor);
        for (int i =1; i <=10; i ++) {
            final  int result = i;
            completionService.submit(new Callable() {
                public Object call() throws Exception {
                    Thread.sleep(new Random().nextInt(5000));   //让当前线程随机休眠一段时间
                    return result;
                }
            });
        }
        System.out.println(completionService.take().get());   //获取执行结果
    }
}

 

参考:

http://cmsblogs.com/?p=2444

https://blog.csdn.net/qq_19431333/article/details/77483763