资讯专栏INFORMATION COLUMN

Future 模式

el09xccxy / 2986人阅读

摘要:模式一种异步计算模式,并支持返回计算结果,在调用获取到计算结果前可以阻塞调用者线程设计原理是针对与模式的一种实现它除了支持特有的特点,还支持的一些操作,比如取消,打断。

FutureTask

future模式:一种异步计算模式,并支持返回计算结果,在调用get()获取到计算结果前可以阻塞调用者线程

FutureTask设计原理

FutureTask是JDK针对与future模式的一种实现,它除了支持future特有的特点,还支持task的一些操作,比如取消,打断。
一个FutureTask就是一个任务的计算单元,是调度的最小单位,它的调度借助于JDK的Executor任务调度模型。需要开发人员创建好FutureTask对象后,并送入到Executor去等待调度

具体的执行过程,像下面是一段FutureTask的伪码描述

创建一个futureTask对象task
提交task到调度器executor等待调度

等待调度中...

如果此时currentThread调取执行结果task.get(),会有几种情况
    
    if task 还没有被executor调度或正在执行中
        阻塞当前线程,并加入到一个阻塞链表中waitNode
    else if task被其它Thread取消,并取消成功 或task处于打断状态
        throw exception
    else if task执行完毕,返回执行结果,或执行存在异常,返回异常信息
        
            
如果此时有另外一个线程调用task.get()
        
    执行过程同上
       

注意:executor在执行FutureTask前,会先判断是否被取消,如果取消就不在执行,但执行后就不可以在取消了

FutureTask 核心部分代码 在futureTask定义task的转态有:
private volatile int state;
private static final int NEW          = 0; // 创建
private static final int COMPLETING   = 1; // 完成
private static final int NORMAL       = 2; // 
private static final int EXCEPTIONAL  = 3; // invoke task 出现异常
private static final int CANCELLED    = 4; // cancel task 
private static final int INTERRUPTING = 5; // interrupting task 
private static final int INTERRUPTED  = 6;
创建一个FutureTask

创建futureTask只需要需要一个callable对象或runnable对象的参数,并在创建时设置状态为NEW

public FutureTask(Callable callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
}
调用get()方法获取执行结果方法
private int awaitDone(boolean timed, long nanos)
        throws InterruptedException {
        final long deadline = timed ? System.nanoTime() + nanos : 0L;
        WaitNode q = null;
        boolean queued = false;
        for (;;) {
            if (Thread.interrupted()) {
                removeWaiter(q);
                throw new InterruptedException();
            }

            int s = state;
            if (s > COMPLETING) {
                if (q != null)
                    q.thread = null;
                return s;
            }
            else if (s == COMPLETING) // cannot time out yet
                Thread.yield();
            else if (q == null)
                q = new WaitNode();
            else if (!queued)
                queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
                                                     q.next = waiters, q);
            else if (timed) {
                nanos = deadline - System.nanoTime();
                if (nanos <= 0L) {
                    removeWaiter(q);
                    return state;
                }
                LockSupport.parkNanos(this, nanos);
            }
            else
                LockSupport.park(this);
        }
}
executor 调度是执行的方法
public void run() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
            Callable c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }
                

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64667.html

相关文章

  • Java多线程进阶(四二)—— J.U.C之executors框架:Future模式

    摘要:本文首发于一世流云的专栏一模式简介模式是多线程设计模式中的一种常见模式,它的主要作用就是异步地执行任务,并在需要的时候获取结果。二中的模式在多线程基础之模式中,我们曾经给出过模式的通用类关系图。 showImg(https://segmentfault.com/img/bVbiwcx?w=1000&h=667); 本文首发于一世流云的专栏:https://segmentfault.co...

    marek 评论0 收藏0
  • Java多线程基础(十一)——Future模式

    摘要:一定义模式用来获取线程的执行结果。案例中的类就是参与者参与者接受请求,然后创建线程进行异步处理。参与者会立即返回以的形式。虚拟数据参与者是用来统一代表参与者与参与者。 一、定义 Future模式用来获取线程的执行结果。在Thread-Per-Message模式中,如果调用一个线程异步执行任务,没有办法获取到返回值,就像:host.request(10,A);而Future模式送出请求后...

    tinyq 评论0 收藏0
  • 多线程设计模式 - Future模式

    摘要:模式是多线程开发中非常常见的一种设计模式,它的核心思想是异步调用。这类似我们日常生活中的在线购物流程,带在购物网看着一件商品时可以提交表单,当订单完成后就可以在家里等待商品送货上门。内部类已经实现了模式,后续再讲 Future模式是多线程开发中非常常见的一种设计模式,它的核心思想是异步调用。这类似我们日常生活中的在线购物流程,带在购物网看着一件商品时可以提交表单,当订单完成后就可以在家...

    edgardeng 评论0 收藏0
  • 批量Future模式

    摘要:批量在模式的讲解中,说到模式是一种支持异步计算并可以返回计算结果,并在返回结果前可以阻塞调用者的线程对象模型。批量模式是在对模式的扩展。 批量 FutureTask 在Future模式的讲解中,说到future模式是一种支持异步计算并可以返回计算结果,并在返回结果前可以阻塞调用者的线程对象模型。批量Future模式是在对Future模式的扩展。比如有,一批FutureTask,我要把这...

    remcarpediem 评论0 收藏0
  • 并发编程中级篇二----并行设计模式----Future模式

    摘要:模式类似于用户提交商品订单,下单成功以后后台异步的执行耗时的业务在包中接口是线程模式的实现,可以来进行异步计算。 Future模式类似于用户提交商品订单,下单成功以后后台异步的执行耗时的业务在java.util.concurrent包中.Future接口是Java线程Future模式的实现,可以来进行异步计算。 showImg(https://segmentfault.com/img/...

    lx1036 评论0 收藏0
  • java Callable与Future模式

    摘要:然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果。如果任务执行结束,无论是正常结束或是中途取消还是发生异常,都返回。如果任务完成前被取消,则返回。参数表示是否中断执行中的线程。 在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口。然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果。我们一般只能采用共享变量或共享存储区...

    Mr_zhang 评论0 收藏0

发表评论

0条评论

el09xccxy

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<