Future 、promise和compleableFuture有什么区别

 在异步处理时,我们常常需要用到这些接口:jdk中的Future和CompleableFuture,netty中的Future和promise。

其中jdk的Future和CompleableFuture在上篇文章中已经讲过了,现在先来讲讲netty的Future和promise。

Future

首先要说明 netty 中的 Future 与 jdk 中的 Future 同名,但是是两个接口,netty 的 Future 继承自 jdk 的 Future

  • jdk Future 只能同步等待任务结束(或成功、或失败)才能得到结果
  • netty Future 可以同步等待任务结束得到结果,也可以异步方式得到结果,但都是要等任务结束

Future需要通过线程来获取结果,在netty中,我们常常通过EventLoopGroup获取Future对象。

随便提一下,excute方法只能提交Runnable任务,没有返回结果。所以我们使用submit方法执行Callable任务才能获取返回结果future。

异步处理:即获取返回结果这个操作是由其他线程(这里是enentLoop)执行的,即在future的操作完成后,enentLoop会执行operationComplete方法。在整个过程中,主线程不会被堵塞,会一直往下执行。

下面通过addListener方法异步获取返回结果:

public class TestNettyFuture {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        NioEventLoopGroup group = new NioEventLoopGroup();
        EventLoop eventLoop = group.next();
        Future<Integer> future = eventLoop.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                log.debug("执行计算");
                Thread.sleep(1000);
                return 70;
            }
        });
//        log.debug("等待结果");
//        log.debug("结果是 {}", future.get());
        future.addListener(new GenericFutureListener<Future<? super Integer>>(){
            @Override
            public void operationComplete(Future<? super Integer> future) throws Exception {
                log.debug("接收结果:{}", future.getNow());
            }
        });
    }
}

 

Promise

Future对象是线程返回得到的结果,依赖线程才能创建。而Promise对象可以主动创建,不需要依赖线程。

netty Promise 不仅有 netty Future 的功能,而且脱离了任务独立存在,只作为两个线程间传递结果的容器,并且可以设置状态(成功还是失败)。

创建promise对象,下面的enentLoop相当于一个线程,用于处理结果的通知和回调

        DefaultPromise<Integer> promise = new DefaultPromise<>(eventLoop);

随便提一下:promise的await方法是非阻塞的,意思是执行await时,当前的代码不会往下走,不会占用CPU,而是会让出CPU资源,用于执行其他任务。当promise被唤醒(设置结果)后,会用EventLoop来通知这个线程来恢复执行没走完的代码。所以我们可以在get()之前使用await,这样就可以解放CPU。

例子:

public class TestNettyPromise {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 1. 准备 EventLoop 对象
        EventLoop eventLoop = new NioEventLoopGroup().next();
        // 2. 可以主动创建 promise, 结果容器
        DefaultPromise<Integer> promise = new DefaultPromise<>(eventLoop);
        new Thread(() -> {
            // 3. 任意一个线程执行计算,计算完毕后向 promise 填充结果
            log.debug("开始计算...");
            try {
                int i = 1 / 0;
                Thread.sleep(1000);
                promise.setSuccess(80);
            } catch (Exception e) {
                e.printStackTrace();
                promise.setFailure(e);
            }

        }).start();
        // 4. 接收结果的线程
        log.debug("等待结果...");
        log.debug("结果是: {}", promise.get());
    }

}

Future & Promise & compleableFuture

  • jdk的future同步等待,并且不能判断结果成功还是失败。
  • netty的future可以非阻塞等待,用getNow如果结果还没有的话返回null
  • promise储存东西+结果(成功或者失败)使用的是setSuccess方法和setFailure方法,用get方法获取返回结果。同时可以在get之前await来让出CPU。
  • 而java的compleableFuture可以异步获取结果,并且储存东西使用的是complete方法,用get方法阻塞获取结果。

功能/名称

jdk Future

netty Future

Promise(这里的任务指的是setSuccess()或者setFailure(),二者都算任务结束)

cancel

取消任务

同上

同上

isCanceled

任务是否取消

同上

同上

isDone

任务是否完成,不能区分成功失败

同上

同上

get

获取任务结果,阻塞等待

同上同上

getNow

-

获取任务结果,非阻塞,还未产生结果时返回 null

同上

await

-

等待任务结束,如果任务失败,不会抛异常,而是通过 isSuccess 判断

同上

sync

-

等待任务结束,如果任务失败,抛出异常

同上

isSuccess

-

判断任务是否成功

同上

cause

-

获取失败信息,非阻塞,如果没有失败,返回null

同上

addLinstener

-

添加回调,异步接收结果

同上

setSuccess

-

-

设置成功结果

setFailure

-

-

设置失败结果

 

 

 

 

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
futurepromise是C++标准库中用于在线程间传递数据的方式之一。std::future作为数据的输出端,用于获取异步操作的结果。而std::promise则作为数据的输入端,用于设置异步操作的结果。 通过std::promise可以设置一个值,而通过std::future可以获取这个值。 在C++标准库中,有两种类型的期望,分别是唯一期望(unique futures)和共享期望(shared futures)。std::future是唯一期望的实例,它只能与一个指定事件相关联。而std::shared_future是共享期望的实例,它可以关联多个事件。 可以使用std::promise和std::future来进行线程间的数据传递。例如,可以使用std::promise来设置一个值,然后通过std::future来获取这个值。示例代码如下: ```C++ std::promise<int> promise; std::future<int> future = promise.get_future(); std::thread producer([&promise(){ // 在子线程中设置值 promise.set_value(42); }); // 在主线程中获取值 int value = future.get(); producer.join(); ``` 在这个例子中,我们创建了一个std::promise对象和一个std::future对象,然后将std::future对象与std::promise对象关联起来。在子线程中,通过调用promise.set_value()方法来设置值为42。在主线程中,通过调用future.get()方法来获取值。最后,我们调用join()方法等待子线程的结束。 另外,可以使用std::shared_future来实现多次访问共享的future对象。示例代码如下: ```C++ std::future<int> fut = std::async([](){return 10;}); std::shared_future<int> shared_fut = fut.share(); std::cout << "value: " << shared_fut.get() << '\n'; std::cout << "its double: " << shared_fut.get() * 2 << '\n'; ``` 在这个例子中,我们创建了一个std::future对象fut,并通过std::async()函数异步执行一个任务,返回值为10。然后,我们使用fut.share()方法创建了一个共享的std::shared_future对象shared_fut。通过调用shared_fut.get()方法多次访问这个共享的future对象。 综上所述,futurepromise是C++标准库中用于在线程间传递数据的方式之一,通过std::future可以获取异步操作的结果,而通过std::promise可以设置异步操作的结果。可以使用std::shared_future实现多次访问共享的future对象。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值