多线程 FutrueTask

继承结构

在这里插入图片描述
FutureTask同时实现了Runnable接口和Future接口,因此可以直接提交给线程池执行,同时也可以返回线程的执行的结果

任务运行状态

    private static final int NEW          = 0;
    private static final int COMPLETING   = 1;
    private static final int NORMAL       = 2;
    private static final int EXCEPTIONAL  = 3;
    private static final int CANCELLED    = 4;
    private static final int INTERRUPTING = 5;
    private static final int INTERRUPTED  = 6;
  • NEW:表示是个新的任务或者还没被执行完的任务。这是初始状态。
  • COMPLETING:任务已经执行完成或者执行任务的时候发生异常,但是任务执行结果或者异常原因还没有保存到outcome字段(outcome字段用来保存任务执行结果,如果发生异常,则用来保存异常原因)的时候,状态会从NEW变更到COMPLETING。但是这个状态会时间会比较短,属于中间状态。
  • NORMAL:任务已经执行完成并且任务执行结果已经保存到outcome字段,状态会从COMPLETING转换到NORMAL。这是一个最终态。
  • EXCEPTIONAL:任务执行发生异常并且异常原因已经保存到outcome字段中后,状态会从COMPLETING转换到EXCEPTIONAL。这是一个最终态。
  • CANCELLED:任务还没开始执行或者已经开始执行但是还没有执行完成的时候,用户调用了cancel(false)方法取消任务且不中断任务执行线程,这个时候状态会从NEW转化为CANCELLED状态。这是一个最终态。
  • INTERRUPTING: 任务还没开始执行或者已经执行但是还没有执行完成的时候,用户调用了cancel(true)方法取消任务并且要中断任务执行线程但是还没有中断任务执行线程之前,状态会从NEW转化为INTERRUPTING。这是一个中间状态。
  • INTERRUPTED:调用interrupt()中断任务执行线程之后状态会从INTERRUPTING转换到INTERRUPTED。这是一个最终态。

状态的流转
在这里插入图片描述

get/cancle

在这里插入图片描述
FutrueTask是基于AQS实现的

FutureTask使用

A线程调用了B线程的FutureTask.run()方法,则A线程会等待B线程执行完之后才会继续执行
1.多个线程同时执行同一任务,每个任务只能执行一次
2.其它线程要等待这个任务执行完了才能继续执行

public class FutureTaskTest {

    private final ConcurrentHashMap<Object, Future<String>> taskCache = new ConcurrentHashMap<>();
    private String executeTask(final String taskName) throws ExecutionException, InterruptedException {
        while (true) {
            Future<String> future = taskCache.get(taskName);
            if (future == null) {
                Callable<String> callable = () -> {
                    Thread.sleep(1000);
                    return taskName;
                };
                FutureTask<String> futureTask = new FutureTask<>(callable);
                //使用ConcurrentHashMap保证并发安全
                future = taskCache.putIfAbsent(taskName,futureTask);
                //保证同名的任务只会被执行一次
                if(future == null){
                    future = futureTask;
                    futureTask.run();
                }
            }
                try {
                    return future.get();
                }catch (CancellationException e){
                    taskCache.remove(taskName, future);
                }
            }
        }

        public static void main(String[] args) throws ExecutionException, InterruptedException {
            FutureTaskTest futureTaskTest = new FutureTaskTest();
            System.out.println(Thread.currentThread().getName() + futureTaskTest.executeTask("abc"));
            System.out.println("等待任务执行完毕");
        }
}

执行结果如下
在这里插入图片描述
主线程调用了FutrueTask的run()方法,主线程等待FutrueTask方法执行完了之后才会继续往下执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值