Runnable、Callable和Future、RunnableFuture、FutureTask
Runnable和Callable
Runnable接口只有一个方法:
public abstract interface Runnable
{
public abstract void run();
}
Callable接口也只有一个方法:
public abstract interface Callable<V>
{
public abstract V call()
throws Exception;
}
同样是用于执行任务,Runnable不带返回值而Callable可以返回值;Callable的执行需要配合ExecutorService,如:
public class Test {
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
Task task = new Task();
final Future<?> result = executor.submit(task);
executor.shutdown();
try {
System.out.println(String.format("阻塞开始时间:%s", System.currentTimeMillis()));
System.out.println(result.get());//get方法阻塞主线程
System.out.println(String.format("阻塞结束时间:%s", System.currentTimeMillis()));
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
class Task implements Callable<Integer>{
@Override
public Integer call() throws Exception {
Thread.sleep(3000);
int sum = 0;
for(int i=0;i<5;i++){
Thread.sleep(100);
sum += i;
System.out.println("子线程在进行计算中");
}
return sum;
}
}
我们可以看到任务提交之后立即返回了Future对象,但是通过Future取值时,get方法阻塞了主线程的执行。
Future接口:
public abstract interface Future<V>
{
public abstract boolean cancel(boolean paramBoolean);
public abstract boolean isCancelled();
public abstract boolean isDone();
public abstract V get()
throws InterruptedException, ExecutionException;
public abstract V get(long paramLong, TimeUnit paramTimeUnit)
throws InterruptedException, ExecutionException, TimeoutException;
}
这个接口常常在异步模式中使用。
RunnableFuture接口:
public abstract interface RunnableFuture<V>
extends Runnable, Future<V>
{
public abstract void run();
}
我们可以看到RunnableFuture接口继承了Runnable和Future接口,这表明我们可以把RunnableFuture当做任务提交,并且可以从中获取到执行结果。
RunnableFuture的常用实现类有FutureTask类。