之前一直都是用Thread或者是实现Runnable接口来使用线程,并且线程没有返回值,今天看书发现原来线程是可以有返回值的,特此记之。
在正式切入本文主题之前,还是先介绍两个朋友interface Callable<V> 和Class FutureTask<V>,如果大家英文好的话,就不用看我蹩脚的翻译了。
1 先介绍interface Callable<V>
-
public interface Callable<V>
A task that returns a result and may throw an exception. Implementors define a single method with no arguments called call.The Callable interface is similar to
Runnable
, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception.-
上面的大体意思是:这个任务返回的结果可能抛出异常。实现者定义看一个没有参数的call方法。这个Callable接口与Runnable接口在为实例可能潜在的被其他线程执行的类而设计方面很类似。然而,一个Runnable并不能返回一个结果,也不能抛出检测异常。
2 一个朋友Class FutureTask<V> A cancellable asynchronous computation. This class provides a base implementation ofFuture
, with methods to start and cancel a computation, query to see if the computation is complete, and retrieve the result of the computation. The result can only be retrieved when the computation has completed; the get method will block if the computation has not yet completed. Once the computation has completed, the computation cannot be restarted or cancelled.A FutureTask can be used to wrap aCallable
orRunnable
object. Because FutureTask implements Runnable, a FutureTask can be submitted to anExecutor
for execution.
大体意思是:一个可撤销的异步计算。这个类实现了Future接口,该接口中有开始、取消计算的、可以查询看计算是否完成的和取得计算结构的方法。只有当计算完成时这个结果才能取得;如果计算还没有完成get方法会一直被阻塞。一旦计算已经开始了,这个计算任务就不能重新开始或者被撤销。一个FutureTask可以用来包装一个Callable或者Runnable对象。因为FutureTask实现了Runnable接口,一个FutureTask可以提交给执行者执行。
大家现在对这两个朋友首先有个感性的认识。
3 使用有返回值线程的步骤 (1) 创建一个类然它实现Callable接口,并实现里面的call方法,返回值在call方法中。 (2) 创建Callable实现类的实例,并用FutureTask包装之。 (3) 启动一个线程将FutureTask的对象作为参数传递给该线程。 (4) 通过FutureTask的get方法获取返回值,由于这个方法会抛出异常,需要捕获异常。
4 一个小例子 import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallAble implements Callable<Integer>{
@Override
public Integer call() throws Exception {
// 模拟耗时操作
Thread.sleep(3000);
// 执行一项任务
int m = 8*9;
// 返回计算结果
return m;
}
public static void main(String[] args) {
int result = 0;
CallAble call = new CallAble();
FutureTask<Integer> task = new FutureTask<Integer>(call);
System.out.println("Start....");
new Thread(task,"hello").start();
try {
result = task.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("result:"+result);
}
}