用途
FutureTask的设计目的,是为了弥补Runnable接口不能获取线程执行结果的缺陷。
通过FutureTask获取异步执行结果的步骤如下:
- 创建一个Callable接口的实现类,并实现它的call()方法,编写好异步执行的具体逻辑,并且可以有返回值。
- 使用Callable实现类的实例构造一个FutureTask实例。
- 使用FutureTask实例作为Thread构造器的target入参,构造新的Thread线程实例。
- 调用Thread实例的start()方法启动新线程,启动新线程的run()方法并发执行。其内部的执行过程为:启动Thread实例的run()方法并发执行后,会执行FutureTask实例的run()方法,最终会并发执行Callable实现类的call()方法。
- 调用FutureTask对象的get()方法阻塞性地获得并发线程的执行结果。
代码示例
package syb.test.busi;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.locks.LockSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class Sample {
private Logger logger = LoggerFactory.getLogger(getClass());
public void test() throws Exception {
// 创建一个Callable对象
Callable<String> callable = () -> {
logger.info("callable execute start");
LockSupport.parkNanos(5L * 1000 * 1000 * 1000);
logger.info("callable execute end");
return "abc";
};
// 由Callable对象,创建FutureTask对象
FutureTask<String> futureTask = new FutureTask<>(callable);
// 由FutureTask对象,创建Thread对象,并启动Thread
new Thread(futureTask).start();
logger.info("thread start OK");
// 通过FutureTask对象,获取线程的执行结果
String result = futureTask.get();
logger.info("result: {}", result);
}
}
--结束--