• 使用CompletableFuture实现异步回调


    基于大佬的例子进行接口改造:https://blog.csdn.net/it_freshman/article/details/80580369

    烧一壶开水有如下几个步骤:

    1. 加水
    2. 打开煤气
    3. 烧水ing—(比较耗时的动作)
    4. 观察,烧水完成
    5. 最后水开之后,关闭煤气
    6. 烧水的过程中,不想等,就直接开了一局游戏

    首先定义一个烧水接口:

    1. public interface BoilWater {
    2. void a_addWater() ;
    3. void b_on() ;
    4. void c_boiling() throws Exception ;
    5. void d_off() ;
    6. // 烧水方法
    7. void make() throws Exception;
    8. void playGame() throws Exception ;
    9. }

    接下来我们对该接口进行实现,本次使用的是抽象类来实现该接口,这样make方法就可以不用具体的实现:

    1. public abstract class AbstractBoilWater implements BoilWater {
    2. protected volatile boolean isReadyFlag = false;
    3. @Override
    4. public void a_addWater() {
    5. System.out.println("1.加水");
    6. }
    7. @Override
    8. public void b_on() {
    9. System.out.println("2.打开煤气");
    10. }
    11. @Override
    12. public void c_boiling() throws Exception {
    13. System.out.println("3-1.烧水中.....");
    14. Thread.sleep(5000);
    15. System.out.println("3-2.水开了");
    16. isReadyFlag = true;
    17. }
    18. @Override
    19. public void d_off() {
    20. System.out.println("4.关闭煤气");
    21. }
    22. //烧水方法
    23. @Override
    24. public abstract void make() throws Exception;
    25. @Override
    26. public void playGame() throws Exception {
    27. Thread.sleep(1200);
    28. if (!isReadyFlag) {
    29. System.out.println("水还没烧开,玩一把游戏");
    30. }
    31. }
    32. }

    接下来进行业务的调用,烧水没好的时候趁机打一把游戏,使用CompletableFuture继承AbstractBoilWater来进行异步调用和监听

    1. public class CompletableFutureBiolWater extends AbstractBoilWater {
    2. @Override
    3. public void make() throws Exception {
    4. a_addWater();
    5. b_on();
    6. CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    7. try {
    8. c_boiling();
    9. } catch (Exception e) {
    10. e.printStackTrace();
    11. }
    12. return 1;
    13. });
    14. //注册事件“监听”
    15. future.whenComplete((v, e) -> {
    16. System.out.println(v);
    17. System.out.println(e);
    18. d_off();
    19. });
    20. while (!future.isDone()) {
    21. playGame();
    22. }
    23. }
    24. }

    编写测试类进行测试

    1. public class testMain {
    2. public static void main(String[] args) {
    3. CompletableFutureBiolWater completableFutureBiolWater= new CompletableFutureBiolWater();
    4. try {
    5. completableFutureBiolWater.make();
    6. } catch (Exception e) {
    7. e.printStackTrace();
    8. }
    9. }
    10. }

    效果如下:

     备注,如果不止烧水这个过程,可能烧水和砍柴可以同时进行,那么可以改造成

    1. public class CompletableFutureBiolWater extends AbstractBoilWater {
    2. @Override
    3. public void make() throws Exception {
    4. a_addWater();
    5. b_on();
    6. CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    7. try {
    8. c_boiling();
    9. } catch (Exception e) {
    10. e.printStackTrace();
    11. }
    12. return 1;
    13. });
    14. //注册事件“监听”
    15. future.whenComplete((v, e) -> {
    16. System.out.println(v);
    17. System.out.println(e);
    18. d_off();
    19. });
    20. //模拟砍柴
    21. CompletableFuture<Integer> futurekanchai = CompletableFuture.supplyAsync(() -> {
    22. try {
    23. c_boiling();
    24. } catch (Exception e) {
    25. e.printStackTrace();
    26. }
    27. return 2;
    28. });
    29. //注册事件“监听”
    30. futurekanchai.whenComplete((v, e) -> {
    31. System.out.println(v);
    32. System.out.println(e);
    33. d_off();
    34. });
    35. while (!future.isDone()&&!futurekanchai.isDone()) {
    36. playGame();
    37. }
    38. }
    39. }

    引发了思考:在工单流程中,可能我们的一个订单其实都走好几个流程,这时候我们就可以使用异步流程的思路来进行设计,减少同步阻塞的时间;这里定义接口是为了方法进行接口的实现,当然也可以使用工程模式来进行优化

  • 相关阅读:
    拿捏指针(一)
    6-1 选择排序
    C++ 11 内敛函数inline
    三级分类部分三级目录无法加载,后端接口能在前端返回所有数据
    【MYSQL】表操作
    【C++】搜索二叉树/KVL树
    【01】区块链技术概述
    空域变换-直方图均衡化(直方图修正)
    CentOS7搭建keepalived+DRBD+NFS高可用共享存储
    python学习第五天之循环结构
  • 原文地址:https://blog.csdn.net/weixin_40593587/article/details/125894996