文章目录
Callable
和Runnable
Diagram
Runnable
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Callable
@FunctionalInterface
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;
}
可以看到,这是一个泛型接口,call()函数返回的类型就是传递进来的V类型。
Future
Future
就是对于具体的Runnable
或者Callable
任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get
方法获取执行结果,该方法会阻塞直到任务返回结果。
Future
提供了三种功能:
1. 判断任务是否完成;
2. 中断任务;
3. 能够获取任务执行结果。
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;
}
cancel
方法用来取消任务,如果取消任务成功则返回true
,如果取消任务失败则返回false
。参数mayInterruptIfRunning
表示是否允许取消正在执行却没有执行完毕的任务,如果设置true
,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning
为true
还是false
,此方法肯定返回false
,即如果取消已经完成的任务会返回false
;如果任务正在执行,若mayInterruptIfRunning
设置为true,则返回true
,若mayInterruptIfRunning
设置为false
,则返回false
;如果任务还没有执行,则无论mayInterruptIfRunning
为true
还是false
,肯定返回true
。isCancelled
方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回true
。sDone
方法表示任务是否已经完成,若任务完成,则返回true
;get()
方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;get(long timeout, TimeUnit unit)
用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null
。
因为Future
只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask
。
FutureTask
FutureTask
实现了RunnableFuture
接口,而RunnableFuture
接口实现了Runnable
和Future
接口。
所以FutureTask
既可以作为Runnable
被线程执行,又可以作为Future
得到Callable
的返回值。
构造器
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
}
使用实例
Callable
+Future
获取结果
Future
一般通过ExecutorService.submit
得到
import java.util.concurrent.*;
public class FutureDemo {
private static Callable<Integer> getCallable() {
return new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getId() + "正在计算");
Thread.sleep(1000);
int res = 0;
for (int i = 0; i < 100; ++i) {
res += i;
}
return res;
}
};
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.SECONDS,
new SynchronousQueue<>());
Callable<Integer> callable = FutureDemo.getCallable();
Future<Integer> future = executorService.submit(callable);
executorService.shutdown();
System.out.println(future.get());
}
}
FutureTask
+Callable
获取结果
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class FutureTaskDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<Integer> callable = FutureDemo.getCallable();
FutureTask<Integer> futureTask = new FutureTask<>(callable);
new Thread(futureTask).start();
System.out.println(futureTask.get());
}
}
如果为了可取消性而使用Future
但又不提供可用的结果,则可以声明Future<?>
形式类型、并返回null
作为底层任务的结果。