Callable和Runnbale一样代表着是线程任务,区别在于Callable有返回值并且可以抛出异常。
创建并启动有返回值的线程的步骤如下:
- 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且该call()方法有返回值。
- 将Callable实例传入FutureTask类。
- 使用FutureTask对象作为Thread对象的target创建并启动新线程。
- 调用FutureTask对象的get()方法来获得子线程结束后的返回值。
示例代码:
MyCallable类:
public class MyCallable implements Callable<Integer>{
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"--->"+i);
sum ++;
}
return sum;
}
}
Main类:
public class Main {
public static void main(String[] args) throws Exception {
System.out.println("----------Callable测试-----------------");
Callable<Integer> myCallable = new MyCallable();
FutureTask<Integer> future = new FutureTask<Integer>(myCallable);
Thread thread = new Thread(future);
thread.start();
try {
int sum = future.get();
System.out.println("funture计算完成:"+sum);
} catch (Exception e) {
e.printStackTrace();
}
}
启动后我们可以看到主线程定义的sum变量成功取到MyCallable实例计算得到的sum值。
扩展:
在Future接口里定义如下几个公共方法来控制它关联的Callable任务。
- boolean cancel(boolean mayInterruptIfRunning):试图取消该Future里关联的Callable任务。
- V get():返回Callable任务里call()方法的返回值。调用该方法将导致程序阻塞,必须等到子线程结束才会得到返回值。
- V get(long timeout,TimeUnit unit):返回Callable任务里call()方法的返回值,该方法让程序最多阻塞timeout长的时间,unit为时间单位,如果经过指定时间后Callable任务依然没有返回值,将会抛出TimeoutException异常。
- boolean isCancelled():如果此Callable任务正常完成前被取消,则返回true。
- boolean isDone():如果Callable任务已经完成,则返回true。