• Future、FutureTask类解析


    Future类

    Future类提供了方法来检查异步调用是否完成、等待异步调用完成并获取异步调用返回结果。get()方法可以对线程进行阻塞,直到异步调用完成并返回结果。cancel()方法可以取消异步方法的执行。

    Future是一个接口,定义了异步线程的返回结果的获取方法,以及异步线程执行的取消方法。下面看源码:

    boolean cancel(boolean mayInterruptIfRunning);
    
    • 1

    尝试取消此任务的执行。如果任务已完成、已取消或由于其他原因无法取消,则此尝试将失败。如果成功,并且在调用cancel时此任务尚未启动,则此任务不应运行。如果任务已经启动,则mayInterruptIfRunning参数确定执行此任务的线程是否应该中断以尝试停止任务。
    此方法返回后,对isDone的后续调用将始终返回true。如果此方法返回true,则对isCancelled的后续调用将始终返回true。

    V get() throws InterruptedException, ExecutionException;
    
    • 1

    如果需要,等待计算完成,然后检索其结果

    V get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
    
    • 1
    • 2

    如果需要,最多等待给定时间以完成计算,然后检索其结果(如果可用)。

    FutureTask类解析

    FutureTask类实现了Future接口定义的方法。FutureTask可以用于包装Callable或Runnable类,因为FutureTask实现了Runnable,所以Future任务可以提交给Executor执行。除了用作独立类之外,该类还提供了受保护的功能,这些功能在创建自定义任务类时可能很有用。

    FutureTask构造函数中可接收Runnable类或Callable类。然后可以调用FutureTask的run方法。如此调用的话,Runnable或Callable中任务就在同一个线程里调用了,属于同步调用了。如下示例:

    public static void main(String[] args) throws InterruptedException, ExecutionException {
            FutureTask<Integer> futureTask=new FutureTask<Integer>(new Callable<Integer>() {
                @Override
                public Integer call() {
                    System.out.println(Thread.currentThread().getName());
                    try{
                        Thread.sleep(5000);
                        System.out.println(666);
                    }catch (Exception e){
    
                    }
                    return RandomUtils.nextInt();
                }
            });
            futureTask.run();
            System.out.println(Thread.currentThread().getName());
            Integer integer = futureTask.get();
            System.out.println(123);
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    返回值如下,且是同步运行:
    在这里插入图片描述
    FutureTask对象也可以交付给另外一个线程或线程池执行,如下:

    //托管给线程池处理
    Future<?> futureResult = Executors.newCachedThreadPool().submit(future);
    //托管给单独线程处理
    new Thread(future).start();
    
    • 1
    • 2
    • 3
    • 4

    此时FutureTask中任务与主线程就是异步执行了。通过get()方法可以阻塞主线程,等待异步线程的返回结果,通过cancel()方法可以取消异步线程执行。一般应用场景为主线程执行任务过多时,采用异步方式同时执行,并在最后等待异步都执行完后,统一结束主线程。

  • 相关阅读:
    FFmpeg 命令:从入门到精通 | ffppeg 命令参数说明
    Unity --- 给物体添加重力
    【EI会议征稿】第三届大数据、人工智能与风险管理国际学术会议 (ICBAR 2023)
    东芝电视Z750的音画效果好吗?调校的够真实吗?
    Unity中Shader光照探针的支持
    嬴图Ultipa | 实时图计算如何将反洗钱进行到底?
    js---笔试题
    基于阿里云微信小程序语音识别
    云轴科技ZStack与华东师范大学共建产教融合基地
    SpringMVC异常处理和自定义拦截器
  • 原文地址:https://blog.csdn.net/qq1309664161/article/details/127658729