前言
续上文AsyncTask中关于FutureTask的介绍,在java编程中除去Runnable和Thread两种方式进行异步操作外,还有使用Callable来进行异步操作。
一、Callable和Runnable
由于Runnable仅仅是进行一个操作,并不能进行返回,故而出现了Callable(猜测)。两者源码:
public interface Runnable {
public abstract void run();
}
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;
}
很明显可以看出run方法无返回值,而Callable下的call方法有返回值。
二、Future
public interface Future<V> {
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<V> implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}
上文源码为FutureTask的类构造和RunnableFuture的实现。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。FutureTask提供了2个构造器:
public FutureTask(Callable<V> callable) {
}
public FutureTask(Runnable runnable, V result) {
}
两者皆可传入。都可以有返回值。
四、使用方式
Callable的使用要借助于ExecutorService,在ExecutorService接口中声明了若干个submit方法的重载版本:
<T> Future<T> submit(Callable<T> task);
<T> Future<T> 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<Integer> result = executor.submit(call);
executor.shutdown();
// FutureTask调用方式
// ExecutorService executor = Executors.newCachedThreadPool();
// CallableTest call= new CallableTest();
// FutureTask<Integer> 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<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("子线程开始运行");
return 1;
}
}
网友评论