无论是 Thread 或是 Runnable,在任务执行完成后无法获取返回结果
- Callable 与 Runnable 区别:
- Callable 接口能返回执行结果,而 Runnable 接口不能返回结果
- Callable 接口的 call() 方法允许抛出异常,而 Runnable 接口的 run() 方法的异常只能在内部处理
Callable、Future、FutureTask
Callable
- Java5 引入了 Callable,它能配合 Future 在任务执行完后获取执行结果
- 该接口的定义如下,声明了一个 call() 方法,返回值为泛型,可抛出异常
public interface Callable<V> {
V call() throws Exception;
}
Future
- Future 接口是用来获取异步计算结果的,该接口声明了以下方法:
- get():获取异步执行的结果,如果没有结果可用,此方法会阻塞到异步计算完成
- isDone():如果任务执行结束,无论是否正常结束还是中途取消或发生异常,都返回 true
- isCanceller():如果任务完成前被取消,则返回 true
-
cancel(boolean mayInterruptRunning):
- 如果任务还没开始,执行 cancel(...) 则方法 false
- 如果任务已经启动,执行 cancel(true) 将以中断执行此任务的方式来试图停止任务,如果停止成功返回 true
- 执行 cancel(false) 方法不会对正在执行的任务线程产生影响,此时返回 false
- 当任务执行完成,执行 cancel(...) 方法将返回 false
FutureTask
- FutureTask 是 Future 的实现,并且实现了 Runnable 接口,它有 3 种状态:
- 未启动:FutureTask.run() 方法还未被执行之前
- 已启动:FutureTask.run() 方法已被调用
- 已完成:FutureTask.run() 方法已执行结束
- 当 FutureTask 处于未启动或已启动状态时,如果我们执行 FutureTask.get() 方法将导致调用线程阻塞
- 当 FutureTask 处于已完成状态时,执行 FutureTask.get() 方法将导致调用线程立即返回结果或者抛出异常
- 当 FutureTask 处于未启动状态时,执行 FutureTask.cancel() 方法将导致此任务永远不会执行
- 当 FutureTask 处于已启动状态时,执行 cancel(true) 方法将以中断执行此任务线程的方式来试图停止任务,如果任务取消成功,cancel(...) 返回 true
- FutureTask 有两种构造函数
public FutureTask(Callable<V> callable) {
}
public FutureTask(Runnable runnable, V result) {
}
代码例子
- 例子一
public class Main {
public static void main(String[] args) {
Callable<String> callable = new MyCallable();
FutureTask<String> futureTask = new FutureTask<String>(callable);
new Thread(futureTask).start();
try {
System.out.println(futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
public static class MyCallable implements Callable<String> {
public String call() throws Exception {
Thread.sleep(1000);
return "linyuan";
}
}
}
- 例子二
public class Main {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Callable<String> callable = new MyCallable();
Future future = executorService.submit(callable);
try {
System.out.println(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
executorService.shutdown();
}
public static class MyCallable implements Callable<String> {
public String call() throws Exception {
Thread.sleep(1000);
return "linyuan";
}
}
}
网友评论