前言
之前我们创建线程是实现Runnable接口,并实现其中的run()方法,这个方法的返回值是void,如果我们想要返回结果怎么办?JDK5给我们提供了一个新的接口,就是Callable接口,其中的call()方法是有返回值的,这个返回值会被Future接口来承接。
正文
我们来看这个call()方法,方法的返回值类型是泛型,可以由用户指定。
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
call()方法的返回结果可以由Future接口来承接,我们来看看Future接口的方法。我们看到2个重载的get()方法就是获取返回结果。
接下来看一个例子:
package org.jimmy.study;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 适配类
FutureTask futureTask = new FutureTask(new Task());
// 启动线程
new Thread(futureTask).start();
// 主线程
System.out.println(Thread.currentThread().getName() + "执行了");
// 获取返回结果
String result = (String) futureTask.get();
System.out.println(result);
}
}
// 实现接口并指定返回值类型
class Task implements Callable<String> {
public String call() throws Exception {
System.out.println(Thread.currentThread().getName() + "执行了");
return "hello";
}
}
执行结果:
Thread-0执行了
main执行了
hello
总结
至此我们学会了3种创建线程的方式,分别是继承Thread类、实现Runnable接口、实现Callable接口。但是,实际中我们并不会使用这几种方式来创建线程,而是用Java提供的线程池,线程池的好处有很多,我们在下一章继续讲。