美文网首页
Guava异步回调

Guava异步回调

作者: M_lear | 来源:发表于2022-07-14 00:07 被阅读0次

写的比较糙,大家可能会看的比较懵。其实本文就是把debug出来的逻辑给记录下来了而已。

正文

从ListeningExecutorService的submit开始分析。

在AbstractListeningExecutorService中重写了newTaskFor方法。
newTaskFor返回的是TrustedListenableFutureTask对象。

AbstractExecutorService的submit逻辑:

    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }

所以submit执行的是TrustedListenableFutureTask的run逻辑。

TrustedListenableFutureTask的run逻辑执行的是TrustedFutureInterruptibleTask的run逻辑。

TrustedFutureInterruptibleTask的run逻辑是继承InterruptibleTask的。

InterruptibleTask的run逻辑:

    public final void run() {
        Thread currentThread = Thread.currentThread();
        if (this.compareAndSet((Object)null, currentThread)) {
            boolean run = !this.isDone();
            T result = null;
            Throwable error = null;

            try {
                if (run) {
                    result = this.runInterruptibly();
                }
            } catch (Throwable var9) {
                error = var9;
            } finally {
                if (!this.compareAndSet(currentThread, DONE)) {
                    this.waitForInterrupt(currentThread);
                }

                if (run) {
                    if (error == null) {
                        this.afterRanInterruptiblySuccess(NullnessCasts.uncheckedCastNullableTToT(result));
                    } else {
                        this.afterRanInterruptiblyFailure(error);
                    }
                }

            }

        }
    }

模板模式。
其中调用的runInterruptibly、afterRanInterruptiblySuccess、afterRanInterruptiblyFailure都是抽象方法,在子类实现。

    @ParametricNullness
    abstract T runInterruptibly() throws Exception;

    abstract void afterRanInterruptiblySuccess(@ParametricNullness T var1);

    abstract void afterRanInterruptiblyFailure(Throwable var1);

子类TrustedFutureInterruptibleTask的这三个方法:

        @ParametricNullness
        V runInterruptibly() throws Exception {
            return this.callable.call();
        }

        void afterRanInterruptiblySuccess(@ParametricNullness V result) {
            TrustedListenableFutureTask.this.set(result);
        }

        void afterRanInterruptiblyFailure(Throwable error) {
            TrustedListenableFutureTask.this.setException(error);
        }

runInterruptibly执行的就是Callable的call方法。

如果把子类实现串进去,整体上InterruptibleTask的run逻辑其实类似于JDK FutureTask的run逻辑。

外部类TrustedListenableFutureTask的set和setException方法(继承自TrustedFuture),都会调用complete方法。

complete方法会调用executeListener执行所有的回调逻辑。

回调逻辑封装在CallbackListener的run:

        public void run() {
            if (this.future instanceof InternalFutureFailureAccess) {
                Throwable failure = InternalFutures.tryInternalFastPathGetFailure((InternalFutureFailureAccess)this.future);
                if (failure != null) {
                    this.callback.onFailure(failure);
                    return;
                }
            }

            Object value;
            try {
                value = Futures.getDone(this.future);
            } catch (ExecutionException var3) {
                this.callback.onFailure(var3.getCause());
                return;
            } catch (Error | RuntimeException var4) {
                this.callback.onFailure(var4);
                return;
            }

            this.callback.onSuccess(value);
        }

Futures.getDone

    @ParametricNullness
    @CanIgnoreReturnValue
    public static <V> V getDone(Future<V> future) throws ExecutionException {
        Preconditions.checkState(future.isDone(), "Future was expected to be done: %s", future);
        return Uninterruptibles.getUninterruptibly(future);
    }

Uninterruptibles.getUninterruptibly

    @ParametricNullness
    @CanIgnoreReturnValue
    public static <V> V getUninterruptibly(Future<V> future) throws ExecutionException {
        boolean interrupted = false;

        try {
            while(true) {
                try {
                    Object var2 = future.get();
                    return var2;
                } catch (InterruptedException var6) {
                    interrupted = true;
                }
            }
        } finally {
            if (interrupted) {
                Thread.currentThread().interrupt();
            }

        }
    }

这里的get不会阻塞,因为Callable任务已经执行完了,这里只是单纯获取执行结果。

回到上面的run逻辑,后面就是根据future的get结果调用对应的回调逻辑。

相关文章

  • 使用guava实现异步回调的简单demo

    使用guava实现异步回调 guava介绍 guava是google针对java异步调用任务的加强框架,它与Jav...

  • Guava异步回调

    写的比较糙,大家可能会看的比较懵。其实本文就是把debug出来的逻辑给记录下来了而已。 正文 从Listening...

  • 异步的实现

    异步的三种实现方式: 回调函数事件Promise 回调函数 回调函数不一定是异步 但是异步一定是回调函数。 事件 ...

  • 同步、异步

    同步:等待结果异步:不等待结果 注意,异步常常伴随回调一起出现,但是异步不是回调,回调也不一定是异步。 【时序图】...

  • 异步和回调

    异步 异步就是「不等结果」,直接进行下一步怎么拿到结果回调可以拿到结果 回调 「回调是一种拿异步结果的方式」「回调...

  • 你不知道的JS(中卷)第七章

    第七章 回调 回调是js异步的基本单元。随着js越来越成熟,对于异步编程的发展,回调已经不够用了。回调表达异步流的...

  • Dart 语法

    回调 dart定义回调 dart使用回调 延时 异步

  • nodeJS回调函数

    NodeJS异步编程的直接体现就是回调函数。 异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了。回调函...

  • Node.js 回调函数

    Node.js 异步编程的直接体现就是回调。 异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了。 回调...

  • 14.回调地狱与 Promise

    回调地狱 为了保证异步代码的执行顺序,将异步代码嵌套到回调函数中,当异步的方法多了,就会产生回调地狱(callba...

网友评论

      本文标题:Guava异步回调

      本文链接:https://www.haomeiwen.com/subject/gowwbrtx.html