FutureTask源码解析

在Java中,我们知道创建线程有两种方式,继承Thread类或者实现Runnable 接口,但是这两种方式都是不能获取方法返回结果的。如果想获取结果,就需要做一些额外的处理,利用共享变量,线程间通信等方式,使用起来就不是很方便,对于不熟悉的人还可能出现线程安全问题。jdk1.5之后,提供了FutureTask类,以及Callable、Future接口,实现了对异步获取返回结果的支持。

Callable
public interface Callable<V> {
    V call() throws Exception;
}

Callable接口是一个泛型接口,只有一个方法,并且有一个返回值,就是泛型V。call方法就是线程实际执行的方法。

Future

Future接口描述了获取返回结果的方法。

public interface Future<V> {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

FutureTask
public class FutureTask<V> implements RunnableFuture<V>

public interface RunnableFuture<V> extends Runnable, Future<V>

FutureTask实现了RunnableFuture接口,而RunnableFuture接口继承Runnable与Future接口。

从Thread的构造函数中,可以看出FutureTask还是以Runnable作为参数传入,因此线程中调用的还是FutureTask的run方法,既然run方法没有返回值,FutureTask应该是使用的某种机制调用了有返回值的call方法。

public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

FutureTask构造函数需要提供一个Callable实现类作为参数,构造函数中又一个state变量被赋值为NEW,用于标记线程状态。

public void run() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
            Callable<V> 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);
        }
    }

在FutureTask的run方法中,显式调用了Callable的call方法,并将返回值赋值给result,然后在set(result)中,存入outcome并更新state状态,唤醒等待结果的线程,outcome就是所需要的结果。f

protected void set(V v) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            outcome = v;      //赋值给outcome
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
            finishCompletion();   //唤醒等待线程等
        }
    }

get方法用于获取异步执行返回值,如果执行完成,则返回结果,如果未完成,就进入等待。

public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FutureTask是一个实现了RunnableFuture接口的类,它继承了Runnable和Future接口。因此,FutureTask既可以被当作一个Runnable来使用,也可以被当作一个Future来使用。 FutureTask实现了Future接口,完成了对Future接口的基本实现。除了实现了Future接口以外,FutureTask还实现了Runnable接口,这意味着它可以交由Executor执行,也可以直接用线程调用执行(futureTask.run())。 FutureTask具有三种执行状态:未启动、已启动和已完成。未启动指的是在调用run()方法之前,FutureTask处于未启动状态。已启动指的是FutureTask对象的run方法正在执行过程中,FutureTask处于已启动状态。已完成指的是FutureTask正常执行结束,或者被取消,或者执行过程中抛出异常而导致中断而结束。 在ThreadPoolExecutor的submit方法中,返回的是一个Future的实现,而这个实现就是FutureTask的一个具体实例。FutureTask帮助实现了具体的任务执行,并与Future接口中的get方法关联起来。 总结起来,FutureTask是一个能够同时担任Runnable和Future角色的类,它可以作为一个任务提交给线程池执行,也可以通过get方法来获取任务执行的结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【第十二篇】Java 线程池Future和FutureTask【重点】](https://blog.csdn.net/weixin_42039228/article/details/123198358)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [FutureTask简介](https://blog.csdn.net/u014516601/article/details/125123415)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值