Callable接口与Runnable接口的区别
- Callable功能更强大些。
- 相比run()方法,可以有返回值。
- 方法可以抛出异常。
- 支持泛型的返回值。
- 需要借助FutureTask类,比如获取返回结果。
Callable接口
Callable
接口类似于Runnable
,因为它们都是为其实例可能由另一个线程执行的类设计的。 然而,Runnable
不返回结果,也不能抛出被检查的异常。
方法
类型和返回值 | 方法和描述 |
---|---|
V | call() 计算一个结果,如果不能这样做,就会抛出一个异常。 |
public interface Callable<V> {
V call() throws Exception;
}
Future接口
可以对具体Runnable、Callable任务的执行结果进行取消、查询是 否完成、获取结果等。FutrueTask是Futrue接口的唯一的实现类。 FutureTask 同时实现了Runnable, Future接口。它既可以作为 Runnable被线程执行,又可以作为Future得到Callable的返回值。
提供方法来检查计算是否完成,等待其完成,并检索计算结果。 结果只能在计算完成后使用方法get
进行检索,如有必要,阻塞,直到准备就绪。 取消由cancel
方法执行。 提供其他方法来确定任务是否正常完成或被取消。 计算完成后,不能取消计算。 如果您想使用Future
,以便不可撤销,但不提供可用的结果,则可以声明Future<?>
表格的类型,并返回null
作为基础任务的结果。
方法
类型和返回值 | 方法和描述 |
---|---|
boolean | cancel(boolean mayInterruptIfRunning) 尝试取消执行此任务。 |
V | get() 等待计算完成,然后检索其结果。 |
V | get(long timeout, TimeUnit unit) 如果需要等待最多在给定的时间计算完成,然后检索其结果(如果可用)。 |
boolean | isCancelled() 如果此任务在正常完成之前被取消,则返回 |
boolean | isDone() 返回 |
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;
}
FutureTask接口
该类提供了一个Future
的基本实现(FutrueTask是Futrue接口的唯一的实现类),具有启动和取消计算的方法,查询计算是否完整,并检索计算结果。 结果只能在计算完成后才能检索; 如果计算尚未完成,则get
方法将阻止。 一旦计算完成,则无法重新启动或取消计算(除非使用runAndReset()
调用计算 )。FutureTask
可用于包装Callable
或Runnable
对象。 因为FutureTask
实现Runnable
,一个FutureTask
可以提交到一个Executor
执行。
除了作为独立类之外,此类还提供了protected
功能,在创建自定义任务类时可能很有用。
构造方法
构造方法和描述 |
---|
FutureTask(Callable<V> callable) 创建一个 |
FutureTask(Runnable runnable, V result) 创建一个 |
方法
修饰语和类型 | 方法和描述 |
---|---|
boolean | cancel(boolean mayInterruptIfRunning) 尝试取消执行此任务。 |
protected void | done() 此任务转换到状态 |
V | get() 等待计算完成,然后检索其结果。 |
V | get(long timeout, TimeUnit unit) 如果需要等待最多在给定的时间计算完成,然后检索其结果(如果可用)。 |
boolean | isCancelled() 如果此任务在正常完成之前取消,则返回 |
boolean | isDone() 返回 |
void | run() 将此未来设置为其计算结果,除非已被取消。 |
protected boolean | runAndReset() 执行计算而不设置其结果,然后将此将来重置为初始状态,如果计算遇到异常或被取消,则不执行此操作。 |
protected void | set(V v) 将此未来的结果设置为给定值,除非此未来已被设置或已被取消。 |
protected void | setException(Throwable t) 导致这个未来报告一个 |
例如
package com.test;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
class SumTotal implements Callable<Integer>{
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 50; i++) {
if (i%20 == 0){
System.out.println("sleep");
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+" " + i);
}
sum += i;
}
return sum;
}
}
public class Main7 {
public static void main(String[] args) {
//实例化对象
SumTotal sumTotal = new SumTotal();
//创建FutureTask
FutureTask<Integer> futureTask = new FutureTask<Integer>(sumTotal);
//执行线程任务
Thread thread = new Thread(futureTask);
thread.setName("线程1");
thread.start();
//获取线程任务返回值
try {
int sum = futureTask.get();
System.out.println(sum);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}