• Future和FutureTask


    1,Future

           java.util.concurrent.Future接口提供了线程不会因为等待返回结果而阻塞的能力。

           设想一个生活场景,用于需要申请车牌,它在提交了申请之后,与长达数小时的等待过程,在这个过程里,用户可以做自己想做的其他事情,而无需一直在窗口等待车牌制作完成。

           在这个过程中,用于可以放弃领取,也可以一直在窗口等待,也可以在窗口看看,能拿走则拿走,不行就在等一会去做别的事。

           Future模式就是提供了这样的能力,让线程可以灵活的确定自己在何时取得结果。

    2,FutureTask

           java.util.concurrent.FutureTask是Future接口在concurrency包中的默认实现,它的主要用途之一是为了AbstractExecutorService提供任务支持,交由AbstractExecutorService执行的任务会被包装成一个FutureTask,以提供延时获取返回值的能力。

           FutureTask间接继承自Future接口和Runnable接口,所以,它同时具备执行任务和获取结果两种能力,FutureTask把实现委托给了其内部的AQS来实现。

           AQS是一个抽象队列同步器,内部维护了一个等待队列和等待状态。

    3,Sync的四种状态

           Sync设计了四种状态,可见,Sync的实现也采用了状态机模式。

    READY:任务准备完毕,可以运行

    RUNNING:任务正在运行

    RAN:任务运行完毕

    CANCELLED:任务取消

    4,Sync的运行

           innerRun的实现很简单:

    1)       检查任务是否为READY状态,如果不是,那么认为已经被调用过了,直接返回。

    2)       设置任务为RUNNING状态,表示当前Sync申领了该任务,如果该任务没有被其它线程修改,那么执行该任务。

    3)       如果其它线程修改了该任务额状态,例如RAN或者CANCELLED,那么中断执行。

    5,Sync的取消

           innerCancel方法的关键点有几处:

    1)       只有READY或者RUN状态的任务才能取消。

    2)       根据参数来决定是否要中断线程阻塞。

    6,Sync获取数据

           innerGet方法用于异步获取数据,其逻辑实现如下:

    1)       如果任务已经执行完成了,那么直接返回结果。

    2)       如果任务尚未完成,那么等待任务完成后返回结果。

           通过对innerGet逻辑实现的分析,可以得出:

    1)       线程访问innerGet时,如果任务不是RAN或者CANCELLED状态,那么线程会被阻塞。

    2)       result来自于innerRun()里callable的返回值

    7,Sync和AQS

         在运行/取消方法里,调用了tryReleaseShared,在取值方法里,调用了tryAcquiredShared,这两个try方法来自于AQS,分别用于在共享模式下线程释放锁和持有锁

    1)       只有已经完成/取消的任务,才能即时获取结果。

    2)       否则任务会等待执行完成或者被取消。

    3)       取消节点是一定会生效的。

  • 相关阅读:
    IO编程
    File类
    对于Java集合理解
    Java泛型
    多线程编程
    异常处理
    Static.final修饰符、super关键字及常量与变量
    java类的基本结构
    数组
    二叉树后序遍历 递归 非递归
  • 原文地址:https://www.cnblogs.com/guanghe/p/13502356.html
Copyright © 2020-2023  润新知