欢迎关注作者简书
csdn传送门
FutureTask介绍
FutureTask是future的实现类,它同时实现了两个接口:Runnable和Future,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
因此我们可以:
- 调用FutureTask对象的run()方法执行
- 调用FutureTask对象的get()方法取结果
- 也可以将FutureTask对象作为callable的实现用线程池或者Thread类去执行。
FutureTask有两个很重要的属性分别是 state 、runner 。futureTask之所以可以支持cancel操作 就是因为这两个属性
其中 state为 枚举值:
NEW 新建 0
COMPLETING 执行中 1
NORMAL 正常 2
EXCEPTIONAL 异常 3
CANCELLED 取消 4
INTERRUPTING 中断中 5
INTERRUNPED 被中断 6
state的状态变化可以有四种方式
NEW->COMPLETING->NORMAL 正常完成的流程
NEW->COMPLETING->EXCEPTIONAL 出现异常的流程
NEW->CANCELED 被取消
NEW->INTERRUNPING->INTERRRUNPTED 被中断
案例
我们用FutureTask写个例子:
package com.concurrency.chapter15;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Random;
import java.util.concurrent.*;
/**
* @program: springcloud-zzx
*
* @description:
*
* @author: zhouzhixiang
*
* @create: 2019-05-14 19:58
*/
public class FutureTaskDemo {
private static final Logger logger = LoggerFactory.getLogger(FutureTaskDemo.class);
public static void main(String[] args) {
// 月饼生产者
final Callable<Integer> productor = new Callable<Integer>() {
@Override public Integer call() throws Exception {
logger.info("月饼制作中。。。。");
Thread.sleep(5000);
return (Integer)new Random().nextInt(1000);
}
};
// 月饼消费者
Runnable customer = new Runnable() {
@Override public void run() {
ExecutorService es = Executors.newSingleThreadExecutor();
logger.info("老板给我来一个月饼");
FutureTask<Integer> futureTask = new FutureTask<>(productor);
es.submit(futureTask);
try {
logger.info(String.format(" 编号[%s]月饼已打包好", futureTask.get()));
logger.info("回家。。。。");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (