5. 异步的应用层实现

1. 概述

      本篇文章分享了应用层的异步是如何实现的,给出了java demo并用响应式编程方式进行了改写。

2. 异步说明

      在开始前我们先明确下本篇文章所述异步的概念。
      以下图中服务A发起对服务B的调用为例
      同步时,一个调用需要消耗一个线程,服务A中Thread1线程调用服务B,等待服务B产生结果,并对结果进行处理。
      异步时,Thread1可以复用,Thread1线程调用服务B后,不用等待服务B返回,它可以继续接收下一个请求,请求结果返回时,由另一个线程(也可能是Thread1)处理。
      这样做有两个好处:
      1. 线程复用,可以用少量线程处理大量请求。
      2. 提高CPU的利用率,IO时CPU没有等待,而是在处理新的请求。

在这里插入图片描述

3. 异步的Java实现

      同步就像打电话,A给B打电话时,B需要接电话,不然A一直等待。
      异步就像发邮件,A给B发邮件时,B不需要在,B只需要把邮箱地址告诉A。
      异步的实现也是依赖“邮箱地址”完成的,只是它有一个更正式的名字,叫回调地址。代码如下所示:

public class AsyncDemo {
    //定义一个邮箱
    private interface Callback{
        void doOnError();
        void doOnSuccess();
    }

    private static class A{
        public void invokeB(String value) {
            AsyncDemo.B b = new AsyncDemo.B();
            //A发起对B的调用,并给B一个邮箱地址
            b.doSomething(value, new AsyncDemo.Callback() {
                @Override
                public void doOnError() {
                    System.out.println("in class A method doOnError!");
                }

                @Override
                public void doOnSuccess() {
                    System.out.println("in class A method doOnSuccess!");
                }
            });
        }
    }

    private static class B{
        public void doSomething(String value, AsyncDemo.Callback callback) {
            //do something
            try {
                Thread.sleep(3000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //B处理完之后,回调地址
            if(StringUtils.isEmpty(value)) {
                callback.doOnError();
            } else {
                callback.doOnSuccess();
            }
        }
    }

    public static void main(String[] args) throws Exception{
        A a = new A();
        a.invokeB("sfsdf");
    }
}

      执行结果如下所示:
在这里插入图片描述

4. 响应式编程方式实现

      什么是响应式编程,以及为什么要用响应式编程可以参考附录中的文章,本篇不在赘述。直接上代码。

public class AsyncWithReactor {
    //此处定义一个邮箱
    private interface Callback{
       void doOnError();
       void doOnSuccess();
    }

    private static class A{
        public Mono invokeB(String value) {
            B b = new B();
            //调用B的返回结果通过Mono包装并返回
            return Mono.create(sink -> {
                //调用B时,传给B一个邮箱地址
                b.doSomething(value, new Callback() {
                    @Override
                    public void doOnError() {
                        System.out.println("in class A method doOnError!");
                        sink.error(new Exception("doOnError"));
                    }

                    @Override
                    public void doOnSuccess() {
                        System.out.println("in class A method doOnSuccess!");
                        sink.success("doOnSuccess");
                    }
                });
            });
        }
    }

    private static class B{
        public void doSomething(String value, Callback callback) {
            //do something
            try {
                Thread.sleep(3000);
            } catch (Exception e) {
                e.printStackTrace();
            }

            if(StringUtils.isEmpty(value)) {
                callback.doOnError();
            } else {
                callback.doOnSuccess();
            }
        }
    }

    public static void main(String[] args) throws Exception{
        A a = new A();
        a.invokeB("aaaa").subscribe(result->{
            System.out.println(result);
        }, e->{
            System.out.println(e);
        });
    }
}

      执行结果如下所示:
在这里插入图片描述

5. 附录

6. 总结

      本篇文章分享了应用层实现异步的方式、好处,给出了java demo并用响应式编程方式进行了改写,本篇文章分享的异步方式也可以用在rpc框架中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值