java并发编程Callable,Future,FutureTask

前言

续上文AsyncTask中关于FutureTask的介绍,在java编程中除去Runnable和Thread两种方式进行异步操作外,还有使用Callable来进行异步操作。

一、Callable和Runnable

由于Runnable仅仅是进行一个操作,并不能进行返回,故而出现了Callable(猜测)。两者源码:

public interface Runnable {
    public abstract void run();
}

public interface Callable {
    /**
     * 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;
}

很明显可以看出run方法无返回值,而Callable下的call方法有返回值。

二、Future

public interface Future {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

为了方便的对线程进行操作,出现了Future接口,对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。
其中cancel用来取消线程操作,由于不一定会取消故而参数名为mayInterruptIfRunning,当传入true的时候表示程序想要取消线程操作,false为不取消,若任务已完成,不论传入什么,返回值一定为false,如果任务未启动,不论传入什么,都是返回true,当任务在执行的时候,传入true,则取消线程,并返回true,若为false,则返回false。
isCancelled表示是否取消了线程操作,若在线程完成前已取消,则返回true,反之则false。
isDone返回任务是否已完成,若完成则返回true。
get() 获取任务最终返回值,线程阻塞,直到线程完成时才返回,源码为一个死循环。
get(long timeout, TimeUnit unit) 获取任务最终返回值,有一个计时器,超过限制时间则返回超时null。

因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask。

三、FutureTask

public class FutureTask implements RunnableFuture


public interface RunnableFuture extends Runnable, Future {
    void run();
}

上文源码为FutureTask的类构造和RunnableFuture的实现。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。FutureTask提供了2个构造器:

public FutureTask(Callable callable) {
}
public FutureTask(Runnable runnable, V result) {
}

两者皆可传入。都可以有返回值。

四、使用方式

Callable的使用要借助于ExecutorService,在ExecutorService接口中声明了若干个submit方法的重载版本:

 Future submit(Callable task);
 Future submit(Runnable task, T result);
Future submit(Runnable task);

示例:

public class HandleClass {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();
        CallableTest call= new CallableTest();
        Future result = executor.submit(call);
        executor.shutdown();

//      FutureTask调用方式
//        ExecutorService executor = Executors.newCachedThreadPool();
//        CallableTest call= new CallableTest();
//        FutureTask result = new FutureTask<>(call);
//        executor.submit(result);
//        executor.shutdown();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        } 
        try {
            System.out.println("task运行结果"+result.get());
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         
    }

}
class CallableTest implements Callable{
    @Override
    public Integer call() throws Exception {
        System.out.println("子线程开始运行");
          
        return 1;
    }
}

你可能感兴趣的:(java并发编程Callable,Future,FutureTask)