java5开始,提供了Callable接口,该接口是Runnable的增强版本,提供了一个call()方法作为执行体,但是call()方法比run()方法功能更强大。
call():有返回值,可以声明抛出异常.
java5提供FutureTask接口来代表Callable接口里面的call方法返回值,并提供了一个FutureTask的实现类,该实现类实现了Runnable接口,可以作为Thread类的target.FutureTask有如下方法:
get():返回任务Callable的call方法的返回值,调用该方法导致程序阻塞,必须等到子线程程序结束以后才会得到返回值。
get(long timeout, TimeUnit unit) 最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)。超时会报异常。
以下示例创建一个线程,并且获得线程的返回值
package com.itcast.heima2;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class ThirdThread implements Callable<Integer>{
@Override
public Integer call() throws Exception {
int i=0;
for(;i<100;i++){
System.out.println(Thread.currentThread().getName()+" 的循环变量i的值:"+i);
}
return i;
}
public static void main(String[] args) {
ThirdThread thirdThread=new ThirdThread();
FutureTask<Integer>future=new FutureTask<Integer>(thirdThread);
for(int i=1;i<=40;i++){
System.out.println(Thread.currentThread().getName()+" 的循环变量i的值:"+i);
if(i==20){
new Thread(future).start();
}
}
try {
System.out.println(" BEGIN " );
System.out.println("子线程的返回值是:"+future.get());
System.out.println(" OVER ");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
由于在主线程里面用get()方法要获取子线程运行接口,主线程最后会阻塞,直到子线程call方法运行结束并返回为止。