FutureTask详解加源码介绍

本文深入探讨Java中的FutureTask,一种用于接收线程返回值的机制。FutureTask不仅可以通过Executor执行,还能直接在线程中调用run方法。文章详细介绍了FutureTask的实现原理,包括其基于AQS的acquire和release操作,以及在JDK1.7和1.8中的不同实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这段时间在公司实习都没时间总结所学的知识,接下来尽量每天一篇输出

----关于FutureTask,最初是在狂刷面试题的时候遇见的,初见觉得十分的陌生,最简单的理解就是,FutureTask是用来接收具有返回值的线程的结果的,具有返回结果的线程的实现方法是Callable()或者是Callable()封装的Runnable(),随着学习,逐渐深入发现没那么简单,感觉读源码,当过了那个令人及其恶心的门槛的时候,真的会沉醉其中

----先贴一张不规范的类图,连接一下其中源码中类和接口之间的关系

----Future状态迁移图

----从图中可以看出FutureTask实现了RunableFuture接口,而RunableFuture接口实现了Runable和Future接口,所以FutureTask可以交给Excutor执行,除此之外还可以在线程中调用FutureTask.run()方法运行。

    //用FutureTask包装Runnable或者Callable对象
    FutureTask<String> future = new FutureTask<String>(new Callable<String>() {
        @Override
        public String call() {               
    });

第一种情况把FutureTask交给Executor或submit执行

    ExecutorService threadPool = Executors.newFixedThreadPool(10);
    Future<String> future = threadPool.submit(task);
    
   

第二种情况在线程中运行Future

    ExecutorService threadPool = Executors.newFixedThreadPool(10);
    CreatThreadDemo4 demo4 = new CreatThreadDemo4();
    //最终实现的是runable接口
    FutureTask<Integer> task = new FutureTask<Integer>(demo4);
    Thread thread = new Thread(task);
    thread.start();


    /***********也可以直接run*************/
    future.run();

----FutureTask的实现

    FutureTask的实现是基于AQS(抽象同步队列)的,每一个基于AQS实现的同步器都会包含两种类型的操作,至少一个acquire操作,这个操作阻塞调用线程,除非直到AQS允许这个线程继续执行,至少一个release操作,这个操作改变AQS状态,这个状态可以允许一个或多个阻塞线程接触阻塞,FutureTask中的方法run()或者cancle()扮演者这个角色

FutureTask的acquire操作由get方法完成

/**
     * @throws CancellationException {@inheritDoc}
     */
    public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }

    /**
     * @throws CancellationException {@inheritDoc}
     */
    public V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        if (unit == null)
            throw new NullPointerException();
        int s = state;
        if (s <= COMPLETING &&
            (s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
            throw new TimeoutException();
        return report(s);
    }

FutureTask中的run()和cancle()

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);
        }
    }
public boolean cancel(boolean mayInterruptIfRunning) {
        if (!(state == NEW &&
              UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
                  mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
            return false;
        try {    // in case call to interrupt throws exception
            if (mayInterruptIfRunning) {
                try {
                    Thread t = runner;
                    if (t != null)
                        t.interrupt();
                } finally { // final state
                    UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
                }
            }
        } finally {
            finishCompletion();
        }
        return true;
    }

----在jdk1.7中,基于复合优于继承的原则,FutureTask声明了一个内部私有类Sync继承了AQS,这个内部类只需要实现状态检查和状态更  

    新的方法,这些方法将控制FutureTask的获取和释放操作。通过内部继承AQS的一个私有类Sync来实现操作代理的;Sync 实现了AQS 

    的tryAcquireShared()和tryReleaseShared()方法

    FutureTask代的get()方法代理到AQS的acquireSharedInterruptibly()方法上

    FutureTask的run()和cancel()方法代理到AQS的release()方法上

    其中源码介绍见https://www.jianshu.com/p/385df6faf585

----在jdk1.8中运用了另一种方法

    介绍见https://www.jianshu.com/p/d0be341748de

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值