前言
今天我们来分析实现多线程的一种方式,实现Callable接口。这种方式有种特殊的地方,就是可以拿到线程返回值。具体怎么实现的呢?我们来研究下。
栗子
我们先举个简单的栗子来看下Callable接口吧。
要首先明白,线程池提交实现Callable接口的线程后会返回一个Future对象,这个对象里包含程序的运行结果。
public class CallableTest {
public static void main(String[] args) throws ExecutionException, InterruptedException,TimeoutException{
//创建一个线程池
ExecutorService executor = Executors.newCachedThreadPool();
Future<String> future = executor.submit(()-> {
//System.out.println("CallableTest");
TimeUnit.SECONDS.sleep(5);
return "CallableTest";
});
System.out.println(future.get());
}
}
可以看到我们可以通过future.get()拿到结果"CallableTest"。
我们也可以设置指定时间后拿到结果,如指定6s后拿到结果。
System.out.println(future.get(4,TimeUnit.SECONDS));
可以看到也拿到了返回结果,如果我们设置4s拿到结果,小于程序运行时间5s,可以看到它抛出了超时异常。java.util.concurrent.TimeoutException。
原理
是不是很神奇?
我们来研究下Callable接口获取返回值的原理。
我们先来看看ExecutorService的submit方法,它接受一个Callable对象,返回一个Future对象。
<T> Future<T> submit(Callable<T> task);
及它的实现。AbstractExecutorService的submit方法。
public <T