1、实现Callable接口来创建线程的方式,可以拿到线程执行结果,结果包含正常执行完成返回的结果,或者发生异常时抛出的异常信息。Callable与Runnable的主要差异就是Runnable的run方法没有返回值,且不抛出异常,Callable的call方法有返回值且可以抛出异常。
2、Future接口中定义了get方法,用来获取线程执行结果的返回值;RunnableFuture接口继承了Future和Runnable,FutureTask实现了RunnableFuture接口,RunnableFuture有入参为Callable类型的构造方法,使用get方法可以获取执行结果。
3、RunnableFuture的get方法为阻塞方法,在线程已执行完成(正常结束,或抛出异常)时,可直接获取执行结果,如果线程未执行完成,则进入阻塞,等待线程执行完成。
4、代码如下:
public class Preloader { ProductInfo loadProductInfo() throws DataLoadException { return null; } private final FutureTask<ProductInfo> future = new FutureTask<ProductInfo>(new Callable<ProductInfo>() { @Override public ProductInfo call() throws DataLoadException { return loadProductInfo(); } }); private final Thread thread = new Thread(future); public void start() { thread.start(); } public ProductInfo get() throws DataLoadException, InterruptedException { try { return future.get(); } catch (ExecutionException e) { Throwable cause = e.getCause(); if (cause instanceof DataLoadException) throw (DataLoadException) cause; else throw LaunderThrowable.launderThrowable(cause); } } interface ProductInfo { } } class DataLoadException extends Exception { }
public class LaunderThrowable { /** * Coerce an unchecked Throwable to a RuntimeException * <p/> * If the Throwable is an Error, throw it; if it is a * RuntimeException return it, otherwise throw IllegalStateException */ public static RuntimeException launderThrowable(Throwable t) { if (t instanceof RuntimeException) return (RuntimeException) t; else if (t instanceof Error) throw (Error) t; else throw new IllegalStateException("Not unchecked", t); } }