Callable
实现Runnable
接口的任务执行没有返回值,如果我们希望线程运算后将结果返回,应该使用Callable
。Callable代表有返回值的任务。
class CallTask implements Callable<String> {
@Override
public String call() throws Exception {
return Thread.currentThread().getName();
}
}
返回当前线程名。
public class ThreadPoolDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//1:使用工厂类获取线程池对象
ExecutorService exec = Executors.newFixedThreadPool(3);
//2:提交任务;
for (int i = 1; i <= 3; i++) {
Future<String> submit = exec.submit(new CallTask());
System.out.println(submit.get());
}
}
}
Future
Future
表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。
- V
get()
:等待计算完成,然后获取其结果。 - boolean
isDone()
:查询任务是否做完。 - boolean
cancel
(boolean mayInterruptIfRunning):试图取消对此任务的执行。 - boolean
isCancelled()
:如果在任务正常完成前将其取消,则返回 true。
class CallTask implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("call()执行中...");
Thread.sleep(3000);
return Thread.currentThread().getName();
}
}
任务增加3秒处理时间。
public class ThreadPoolDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//1:使用工厂类获取线程池对象
ExecutorService exec = Executors.newFixedThreadPool(3);
//2:提交任务;
Future<String> future = exec.submit(new CallTask());
while (!future.isDone()) {
System.out.println("子进程执行中...");
Thread.sleep(1000);
}
System.out.println(future.get());
}
}
FutureTask
public class FutureTask<V> implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V>
FutureTask
类是Future
接口的一个实现。FutureTask 类实现了 RunnableFuture 接口, RunnableFuture 继承了Runnable
接口和Future
接口。
所以,FutureTask 既可以作为 Runnable 被线程执行,也可以作为 Future 得到传入的 Callable 对象的返回值。
class CallTask implements Callable<String> {
@Override
public String call() throws Exception {
return Thread.currentThread().getName();
}
}
public class ThreadPoolDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//1:使用工厂类获取线程池对象
ExecutorService exec = Executors.newFixedThreadPool(3);
//2:提交任务;
FutureTask<String> futureTask = new FutureTask<>(new CallTask());
Future<?> submit = exec.submit(futureTask);
System.out.println(submit.get());
System.out.println(futureTask.get());
}
}
结果可见,FutureTask对象可以当作一个有返回值的 Runnable 任务来使用。
FutureTask<String> futureTask = new FutureTask<>(new CallTask())
相当于把 Callable 任务转换为 Runnable 任务。然后传参线程池方法Future<?> submit(Runnable task)
进行任务执行。
futureTask.get()
获取异步运算的结果。
综上所述,FutureTask 对象作为任务执行对象,任务执行后,还可以直接获取任务执行的结果。完美!!