【多线程研究专题三】【FutureTask与Callable的本质】

吐槽:以前看了好多文章和书籍讲FutureTask,讲的很细,但不得要领,还是会忘。绝知此事要躬行,还是得自己亲自分析下源码。

1、FutureTask本质上是Runnable和Callable的实现类,就是一个任务类,主函数也是run()。
2、FutureTask实现了异步任务,怎么实现的?是因为Callable?
      不是。Callable.call()与Runnable.run()只是一个很普通的方法,是同步方法。异步方法是因为FutureTask的实现机制,使用了Guard Suspension模式。

下面说下Guard Suspension模式的核心思想,以及Future是如何实现的:

GS模式作用:把同步方法,变为异步方法。
GS模式思想:线程A执行与一般同步方法无异,主要是线程B(异步任务,如FutureTask所在的线程)的执行不一样:异步任务的get()方法调用wait()方法进入wait状态(java有多种实现),等待同步方法call()执行结束(在线程B中运行),通知get方法取消wait状态。这就是GS的主要思想。
示意图如下:



从上图可见,run()和get()是主要角色,run的代码如下:

set()其实很简单,就是返回outcome结果,并调用finishCompletion(),通知get()方法,取消wait状态。


再看下get(),awaitDone()就是进入了wait()状态。其实现是一个for(;;)循环。对应上面的finishCompletion(),我们只需要关注思想,先不管具体实现。
反正awatiDone()的无限循环会被finishCompletion()打破。然后调用report()

    public Vget() throws InterruptedException, ExecutionException {
        int s = state ;
        if ( s <= COMPLETING )
            s = awaitDone( false , 0L);
        return report( s );
    }
report()实现如下。就是把set()里面设置的outcome传给x,然后返回。
    @SuppressWarnings ( "unchecked" )
    private Vreport( int s ) throws ExecutionException {
        Object x = outcome ;
        if ( s == NORMAL )
            return (V) x ;
        if ( s >= CANCELLED )
            throw new CancellationException();
        throw new ExecutionException((Throwable) x );
    }

小结:
1. FutureTask的核心思想是:通过awaitDone()和finishCompletion()实现异步操作。
2. 第1点,被封装为get()/set()。其中get()被外部线程A调用,set()被线程B--FutureTask的run()调用。
3.Callable的call()本质上是同步方法。
4.FutureTask的主函数只运行callable方法,Runnable.run()是通过一个adapter转为Callable的()。
    public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }

Executors.callable定义如下:
    public static <T> Callable<T> callable(Runnable task, T result) {
        if (task == null)
            throw new NullPointerException();
        return new RunnableAdapter<T>(task, result);
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值