Callable,Future和FutureTask详解

1.Callable和Runnable

看Callable接口:

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接口:

public
interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

Callable和Runnable都代表着任务,不同之处在于Callable有返回值,并且能抛出异常,Runnable任务执行结束之后没有返回值。Callable一般和Future一起使用,可以获取任务返回结果。

2.Future接口

Future就是对具体的Callable和Runnable任务进行操作,如:取消任务,查询任务是否完成,获取任务完成之后的返回结果(如果有返回值)。看代码:

public interface Future<V> {
    // 用于取消任务
    boolean cancel(boolean mayInterruptIfRunning);
    // 任务是否被取消成功,如果取消成功,返回true
    boolean isCancelled();
    // 任务是否已经完成,如果完成,返回true
    boolean isDone();
    // 获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回
    V get() throws InterruptedException, ExecutionException;
   // 获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。 
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

由接口可知,Future提供了四种功能:

  •   取消任务
  •   判断任务是否取消成功
  •   判断任务是否完成
  •   获取任务执行结果

通过一个Demo来理解Future的用法:

public class FutureTest {
    public static class Task implements Callable<String>{
        
        @Override
        public String call() throws Exception {
            System.out.println("开始执行任务。。。");
            return "callable";
        }
        
    }
    
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService es = Executors.newCachedThreadPool();
        List<Future<String>> results = new ArrayList<Future<String>>();
        for(int i = 0;i<100;i++){
            results.add(es.submit(new Task()));
        }

        for(Future<String> res : results){
            System.out.println(res.get());
        }
        
    }
    
}

3.FutureTask

public class FutureTask<V> implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V> {
    void run();
}

从代码可知:FutureTask既可以作为Runnable被线程执行,又具有Future的功能。

FutureTask的两种使用方式:

使用方式一:FutureTask+Thread

public class FutureTest {
    public static class Task implements Callable<String>{
        
        @Override
        public String call() throws Exception {
            System.out.println("开始执行任务。。。");
            return "callable";
        }
        
    }
    
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //创建FutureTask对象,并传入一个实现了Callable接口的对象作为构造参数
        FutureTask<String> futureTask = new FutureTask<String>(new Task());
        //创建Thread并启动
        Thread thread = new Thread(futureTask);
        thread.start();
    }
    
}

使用方式二:FutureTask+ExecutorService

public class FutureTest {
    public static class Task implements Callable<String>{
        
        @Override
        public String call() throws Exception {
            System.out.println("开始执行任务。。。");
            return "callable";
        }
        
    }
    
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService es = Executors.newCachedThreadPool();
        FutureTask<String> futureTask = new FutureTask<String>(new Task());
        es.submit(futureTask);
    }
    
}
原文地址:https://www.cnblogs.com/51life/p/10142804.html