栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA:响应式编程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA:响应式编程

序言

通常我们编写的Java程序,都是一行执行完了,再执行下一行.上一行没有执行完,下一行就不会执行.这种就是指令式编程.

另外一种就是响应式编程,既可以满足当前一行命令还没有执行完时,下一行命令就可以启动执行.当需要上一行命令的结果时再去获取相关值(或者上一行结果在执行完后主动的告诉我们)cuiyaonan2000@163.com

CompletableFuture

在Java8 之前就有Future提供了响应式编程的实现方式.但是有一些缺陷.所以提供了CompletableFuture,从这个名字上我们就能知道该新特性是比之前的Future更完善和强大的^_^.---其实如果你要自己实现也是可以的,使用多线程的方式Runnable来获取其它线程返回的值cuiyaonan2000@163.com

包目录

CompletableFuture 在 java.util.concurrent这个万众瞩目的目录下 .多少同学的面试必背目录cuiyaonan2000@163.com

构造方法

如下只有一个公有的.还有个私有的构造方法,但是我们没法调用.

示例--这种构造方法的创建对象,实际使用的时候比较少
package cui.yao.nan.completablefuture;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;


public class Test {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        //CompletableFuture 的构造方法只有这种
        CompletableFuture completableFuture = new CompletableFuture();

        //此处必须要设置,否则completableFuture.get()就会一直阻塞
        completableFuture.complete("cuiyaonan2000@163.com");

        //get()方法会一直阻塞直到 Future 完成.所以必须有上面这部模拟完成
        String result = completableFuture.get();

        System.out.println(result);


    }
}


异步任务

如上构造方法创建一个子任务的方式其实非常少用.

实际使用CompletableFuture使用的创建异步子任务的方式还是要靠如下的方法cuiyaonan2000@163.com

另:CompletableFuture的方法中 Async 后缀的均为异步操作

runAsync

由上runAsyn其实就是传入一个Runnable的对象,执行异步任务.

那Runnable是有啥子特点呢???就是没有返回值cuiyaonan2000@163.com

runAsync是Runnable任务,不带返回值的,如果入参有executor,则使用executor来执行异步任务

 CompletableFuture runAsync = CompletableFuture.runAsync(()->{
     System.out.println("cuiyaonan2000@163.com begin");
     try {
         Thread.sleep(1000);
     } catch (InterruptedException e) {
         e.printStackTrace();
     }
     System.out.println("cuiyaonan2000@163.com end");
 });


//如下的get很重要,如果没有get,则当主程序运行完了.子线程也会挂掉,即     System.out.println("cuiyaonan2000@163.com end");不会执行
 runAsync.get();

supplyAsync

supplyAsync是带返回值的,如果入参不带executor,则默认使用ForkJoinPool.commonPool()作为执行异步任务的线程池;否则使用executor执行任务。

主要区别就是线程中必须有return,可以参考Callable

  CompletableFuture supplyAsync = CompletableFuture.supplyAsync(()->{
      System.out.println("cuiyaonan2000@163.com begin");
      try {
          Thread.sleep(1000);
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
      System.out.println("cuiyaonan2000@163.com end");
      return "1";
  });

//如下的get很重要,如果没有get,则当主程序运行完了.子线程也会挂掉,即     System.out.println("cuiyaonan2000@163.com end");不会执行
System.out.println(supplyAsync.get());

任务触发器

该类方法主要是当异步任务完成后设置的,所以它是提供给任务的触发器,所包含的方法如下:

complete

直接让异步任务结束,同时可以这只一个返回值.

CompletableFuture whenComplete = CompletableFuture.supplyAsync(()->{
    System.out.println("cuiyaonan2000@163.com begin");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
        System.out.println("cuiyaonan2000@163.com end");
        return "1";
    }).whenComplete((a,e)->{
         System.out.println("异步任务返回的结果是:" +a +"  抛出的异常是:" +e);
         int i =1/0;
    }).exceptionally(e->{
         System.out.println("异常信息是"+e.getCause());
         return "2";
     });
     
whenComplete.complete(11);
     
System.out.println(whenComplete.get());

completeExceptionally

这个更狠 直接让子任务异常退出,注意是异常退出.即使有异常捕获也不能抓到.

        CompletableFuture whenComplete = CompletableFuture.supplyAsync(()->{
            System.out.println("cuiyaonan2000@163.com begin");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("cuiyaonan2000@163.com end");
            return "1";
        }).whenComplete((a,e)->{
            System.out.println("异步任务返回的结果是:" +a +"  抛出的异常是:" +e);
            int i =1/0;
        }).exceptionally(e->{
            System.out.println("异常信息是"+e.getCause());
            return "2";
        });
        whenComplete.completeExceptionally(new Exception("121323"));
        System.out.println(whenComplete.get());

whenComplete

顾明思议当任务完成时触发.同时它提供了多钟,主要的有2种.即同步的,还是异步的.        

CompletableFuture whenComplete = CompletableFuture.supplyAsync(()->{
    System.out.println("cuiyaonan2000@163.com begin");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("cuiyaonan2000@163.com end");
    return "1";
}).whenComplete((a,e)->{
    System.out.println("异步任务返回的结果是:" +a +"  抛出的异常是:" +e);
});

//如下的get很重要,如果没有get,则当主程序运行完了.子线程也会挂掉,即     System.out.println("cuiyaonan2000@163.com end");不会执行

whenComplete.get();

exceptionally

此即为try cahtch 的finally 接收异常信息,并返回一个结果

CompletableFuture whenComplete = CompletableFuture.supplyAsync(()->{
    System.out.println("cuiyaonan2000@163.com begin");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
        System.out.println("cuiyaonan2000@163.com end");
        return "1";
   }).whenComplete((a,e)->{
       System.out.println("异步任务返回的结果是:" +a +"  抛出的异常是:" +e);
       int i =1/0;
   }).exceptionally(e->{
       System.out.println("异常信息是"+e.getCause());
       return "2";
   });


whenComplete.get();

thenApply

 

runAsync或者supplyAsync的任务在get()时整个主进程都会阻塞,除非运行结束.所以可以只用thenApply在包一层.

thenApply会获取supplyAsync或者runAsync的返回值,然后在处理后在返回一个.感觉没毛用.因为thenapply也必须要get.

另:thenApply返回的是另外一个CompletableFuture.

        CompletableFuture thenApply = CompletableFuture.supplyAsync(()->{
            System.out.println("cuiyaonan2000@163.com thenApply  begin");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("cuiyaonan2000@163.com thenApply end");
            return "1";
        }).thenApply((a)->{
            return "异步调用返回a"+a;
        }).thenApply((a)->{
            return "异步调用返回a"+a;
        });
        System.out.println(thenApply.get());

thenAccept与 thenRun

thenAccept 与 thenRun 也是返回另外一个CompletableFuture

跟thenApply不同之处在于,不会返回值,只是做一些处理.

// thenAccept() example
CompletableFuture.supplyAsync(() -> {
    return ProductService.getProductDetail(productId);
}).thenAccept(product -> {
    System.out.println("Got product detail from remote service " + product.getName())
});




// thenRun() example
CompletableFuture.supplyAsync(() -> {
    // Run some computation  
}).thenRun(() -> {
    // Computation Finished.
});

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/703932.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号