在并发多线程场景下,存在需要获取各线程的异步执行结果,这时,就可以通过ExecutorService线程池结合Callable、Future来实现。
我们先来写一个简单的例子——
public class ExecutorTest { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService executor = Executors.newSingleThreadExecutor(); Callable callable = new MyCallable(); Future future = executor.submit(callable); System.out.println("打印线程池返回值:" + future.get()); } } class MyCallable implements Callable{ @Override public String call() throws Exception { return "测试返回值"; } }
执行完成后,会打印出以下结果:
打印线程池返回值:测试返回值
可见,线程池执行完异步线程任务,我们是可以获取到异步线程里的返回值。
那么,ExecutorService、Callable、Future实现有返回结果的多线程是如何实现的呢?
首先,我们需要创建一个实现函数式接口Callable的类,该Callable接口只定义了一个被泛型修饰的call方法,这意味着,需要返回什么类型的值可以由具体实现类来定义——
@FunctionalInterface public interface Callable{ V call() throws Exception; }
因此,我自定义了一个实现Callable接口的类,该类的重写了call方法,我们在执行多线程时希望返回什么样的结果,就可以在该重写的call方法定义。
class MyCallable implements Callable{ @Override public String call() throws Exception { return "测试返回值"; } }
在自定义的MyCallable类中,我在call方法里设置一个很简单的String返回值 “测试返回值”,这意味着,我是希望在线程池执行完异步线程任务时,可以返回“测试返回值”这个字符串给我。
接下来,我们就可以创建该MyCallable类的对象,然后通过executor.submit(callable)丢到线程池里,线程池里会利用空闲线程来帮我们执行一个异步线程任务。
ExecutorService executor = Executors.newSingleThreadExecutor(); Callable callable = new MyCallable(); Future future = executor.submit(callable);
值得注意一点是,若需要实现获取线程返回值的效果