用Java实现Promise的难点总结

自Promise被纳入ECMAScript6标准后,各大浏览器几乎都实现了Promise标准。

以下是ecmascript6里promise的典型用法,为了解决一个线程的任务完成后,再去执行另一个任务。

var promise = new Promise(function(resolve, reject) {
      $.ajax({
           success: function() {
                 resolve();
           },
           failure: function() {
                 reject();
           }
      })
});

promise.then(function() {
       //调用了resolve或者reject之后
});

 

Java实现Promise相比较ECMAScript6来说,有些不同。

Javascript不管怎么样都是单线程的,即使ajax在浏览器内核层面表现出多线程,但是执行到js端还是单线程的。而在java上实现promise机制则复杂的多。具体表现在:

1)即使在上一个线程执行任务后,下一个任务可以在同一个线程中执行,但是加入任务的操作不得不是同步的

Netty4源码:io.netty.util.concurrent.DefaultPromise

    @Override
    public Promise<V> addListener(GenericFutureListener<? extends Future<? super V>> listener) {
        if (listener == null) {
            throw new NullPointerException("listener");
        }

        if (isDone()) {
            notifyLateListener(listener);
            return this;
        }
        //加入时必须同步
        synchronized (this) {
            if (!isDone()) {
                if (listeners == null) {
                    listeners = listener;
                } else {
                    if (listeners instanceof DefaultFutureListeners) {
                        ((DefaultFutureListeners) listeners).add(listener);
                    } else {
                        final GenericFutureListener<? extends Future<V>> firstListener =
                                (GenericFutureListener<? extends Future<V>>) listeners;
                        listeners = new DefaultFutureListeners(firstListener, listener);
                    }
                }
                return this;
            }
        }

        notifyLateListener(listener);
        return this;
    }

 

2)在多个平行任务(线程)结束后,再去执行一个任务的case (Promise.all)的时候,判断任务是否结束的计数操作也不得不是同步的。

Netty源码:io.netty.channel.group.DefaultChannelGroupFuture

    private final ChannelFutureListener childListener = new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            boolean success = future.isSuccess();
            boolean callSetDone;
            // 判断所有的task是否已经结束也必须同步
            synchronized (DefaultChannelGroupFuture.this) {
                if (success) {
                    successCount ++;
                } else {
                    failureCount ++;
                }

                callSetDone = successCount + failureCount == futures.size();
                assert successCount + failureCount <= futures.size();
            }

            if (callSetDone) {
                if (failureCount > 0) {
                    List<Map.Entry<Channel, Throwable>> failed =
                            new ArrayList<Map.Entry<Channel, Throwable>>(failureCount);
                    for (ChannelFuture f: futures.values()) {
                        if (!f.isSuccess()) {
                            failed.add(new DefaultEntry<Channel, Throwable>(f.channel(), f.cause()));
                        }
                    }
                    setFailure0(new ChannelGroupException(failed));
                } else {
                    setSuccess0();
                }
            }
        }
    };

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java中,并没有内置的Promise类,但是可以使用一些库或框架来实现Promise的功能。其中一个常用的库是CompletableFuture,它提供了一个强大的异步编程工具,可以用来处理异步任务的完成或失败。 使用CompletableFuture,你可以通过以下步骤创建和使用Promise: 1. 创建一个CompletableFuture对象,可以通过CompletableFuture类的静态方法提供一个初始值,或者使用构造函数创建一个空的CompletableFuture对象。 2. 使用`thenApply()`、`thenAccept()`、`thenRun()`等方法,将回调函数附加到CompletableFuture对象上。这些方法允许你定义在Future完成时要执行的操作。 3. 在合适的时候,通过调用CompletableFuture的`complete()`、`completeExceptionally()`、`cancel()`等方法,将结果或异常传递给CompletableFuture对象。 4. 当你需要等待CompletableFuture的完成时,可以使用`get()`方法阻塞当前线程,直到Future完成并返回结果。你还可以使用`join()`方法等待Future的完成,但不会抛出异常。 总的来说,CompletableFuture提供了一种简洁而灵活的方式来处理异步任务的结果。它允许你链式地组合多个异步操作,并在每个操作完成后执行特定的操作。 是Netty4源码中的一段代码,展示了如何在Promise对象中添加监听器并触发相应的回调函数。 是一个使用Promise的典型例子,在这个例子中,使用Promise来处理异步的AJAX请求。 提到了Java实现Promise模式的另一个类:FutureTask。FutureTask是Java标准库中实现了Future接口的具体类,可以看作是Promise模式的参与者实例。 综上所述,虽然Java中没有内置的Promise类,但是可以使用CompletableFuture等库来实现Promise的功能。这些库提供了一种方便的方式来处理异步任务的完成和失败,并允许你以链式的方式组合多个异步操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值