千家信息网

如何使用Java异步编程

发表于:2025-01-16 作者:千家信息网编辑
千家信息网最后更新 2025年01月16日,这篇文章主要介绍"如何使用Java异步编程",在日常操作中,相信很多人在如何使用Java异步编程问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"如何使用Java异步编程"
千家信息网最后更新 2025年01月16日如何使用Java异步编程

这篇文章主要介绍"如何使用Java异步编程",在日常操作中,相信很多人在如何使用Java异步编程问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"如何使用Java异步编程"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1、创建异步线程任务

根据supplier创建CompletableFuture任务

//使用内置线程ForkJoinPool.commonPool(),根据supplier构建执行任务public static  CompletableFuture supplyAsync(Supplier supplier)//指定自定义线程,根据supplier构建执行任务public static  CompletableFuture supplyAsync(Supplier supplier, Executor executor)

根据runnable创建CompletableFuture任务

//使用内置线程ForkJoinPool.commonPool(),根据runnable构建执行任务public static CompletableFuture runAsync(Runnable runnable)//指定自定义线程,根据runnable构建执行任务public static CompletableFuture runAsync(Runnable runnable, Executor executor)
  • 使用示例

ExecutorService executor = Executors.newSingleThreadExecutor();CompletableFuture rFuture = CompletableFuture        .runAsync(() -> System.out.println("hello siting"), executor);//supplyAsync的使用CompletableFuture future = CompletableFuture        .supplyAsync(() -> {            System.out.print("hello ");            return "siting";        }, executor);//阻塞等待,runAsync 的future 无返回值,输出nullSystem.out.println(rFuture.join());//阻塞等待String name = future.join();System.out.println(name);executor.shutdown(); // 线程池需要关闭--------输出结果--------hello sitingnullhello siting

常量值作为CompletableFuture返回

//有时候是需要构建一个常量的CompletableFuturepublic static  CompletableFuture completedFuture(U value)

2 、线程串行执行

任务完成则运行action,不关心上一个任务的结果,无返回值

public CompletableFuture thenRun(Runnable action)public CompletableFuture thenRunAsync(Runnable action)public CompletableFuture thenRunAsync(Runnable action, Executor executor)
  • 使用示例

CompletableFuture future = CompletableFuture        .supplyAsync(() -> "hello siting", executor)        .thenRunAsync(() -> System.out.println("OK"), executor);executor.shutdown();--------输出结果--------OK

任务完成则运行action,依赖上一个任务的结果,无返回值

public CompletableFuture thenAccept(Consumer action)public CompletableFuture thenAcceptAsync(Consumer action)public CompletableFuture thenAcceptAsync(Consumer action, Executor executor)
  • 使用示例

ExecutorService executor = Executors.newSingleThreadExecutor();CompletableFuture future = CompletableFuture        .supplyAsync(() -> "hello siting", executor)        .thenAcceptAsync(System.out::println, executor);executor.shutdown();--------输出结果--------hello siting

任务完成则运行fn,依赖上一个任务的结果,有返回值

public  CompletableFuture thenApply(Function fn)public  CompletableFuture thenApplyAsync(Function fn)        public  CompletableFuture thenApplyAsync(Function fn, Executor executor)
  • 使用示例

ExecutorService executor = Executors.newSingleThreadExecutor();CompletableFuture future = CompletableFuture        .supplyAsync(() -> "hello world", executor)        .thenApplyAsync(data -> {            System.out.println(data); return "OK";        }, executor);System.out.println(future.join());executor.shutdown();--------输出结果--------hello worldOK

thenCompose - 任务完成则运行fn,依赖上一个任务的结果,有返回值

  • 类似thenApply(区别是thenCompose的返回值是CompletionStage,thenApply则是返回 U),提供该方法为了和其他CompletableFuture任务更好地配套组合使用

public  CompletableFuture thenCompose(Function> fn) public  CompletableFuture thenComposeAsync(Function> fn)public  CompletableFuture thenComposeAsync(Function> fn,  Executor executor)
  • 使用示例

//第一个异步任务,常量任务CompletableFuture f = CompletableFuture.completedFuture("OK");//第二个异步任务ExecutorService executor = Executors.newSingleThreadExecutor();CompletableFuture future = CompletableFuture        .supplyAsync(() -> "hello world", executor)        .thenComposeAsync(data -> {            System.out.println(data); return f; //使用第一个任务作为返回        }, executor);System.out.println(future.join());executor.shutdown();--------输出结果--------hello worldOK

3 、线程并行执行

两个CompletableFuture[并行]执行完,然后执行action,不依赖上两个任务的结果,无返回值

public CompletableFuture runAfterBoth(CompletionStage other, Runnable action)public CompletableFuture runAfterBothAsync(CompletionStage other, Runnable action)public CompletableFuture runAfterBothAsync(CompletionStage other, Runnable action, Executor executor)
  • 使用示例

//第一个异步任务,常量任务CompletableFuture first = CompletableFuture.completedFuture("hello world");ExecutorService executor = Executors.newSingleThreadExecutor();CompletableFuture future = CompletableFuture        //第二个异步任务        .supplyAsync(() -> "hello siting", executor)        // () -> System.out.println("OK") 是第三个任务        .runAfterBothAsync(first, () -> System.out.println("OK"), executor);executor.shutdown();--------输出结果--------OK

两个CompletableFuture[并行]执行完,然后执行action,依赖上两个任务的结果,无返回值

//第一个任务完成再运行other,fn再依赖消费两个任务的结果,无返回值public  CompletableFuture thenAcceptBoth(CompletionStage other,        BiConsumer action)//两个任务异步完成,fn再依赖消费两个任务的结果,无返回值     public  CompletableFuture thenAcceptBothAsync(CompletionStage other,        BiConsumer action)  //两个任务异步完成(第二个任务用指定线程池执行),fn再依赖消费两个任务的结果,无返回值                public  CompletableFuture thenAcceptBothAsync(CompletionStage other,        BiConsumer action, Executor executor)
  • 使用示例

//第一个异步任务,常量任务CompletableFuture first = CompletableFuture.completedFuture("hello world");ExecutorService executor = Executors.newSingleThreadExecutor();CompletableFuture future = CompletableFuture        //第二个异步任务        .supplyAsync(() -> "hello siting", executor)        // (w, s) -> System.out.println(s) 是第三个任务        .thenAcceptBothAsync(first, (s, w) -> System.out.println(s), executor);executor.shutdown();--------输出结果--------hello siting

两个CompletableFuture[并行]执行完,然后执行action,依赖上两个任务的结果,有返回值

//第一个任务完成再运行other,fn再依赖消费两个任务的结果,有返回值public  CompletableFuture thenCombine(CompletionStage other,   BiFunction fn)//两个任务异步完成,fn再依赖消费两个任务的结果,有返回值public  CompletableFuture thenCombineAsync(CompletionStage other,        BiFunction fn)   //两个任务异步完成(第二个任务用指定线程池执行),fn再依赖消费两个任务的结果,有返回值        public  CompletableFuture thenCombineAsync(CompletionStage other,        BiFunction fn, Executor executor)
  • 使用示例

//第一个异步任务,常量任务CompletableFuture first = CompletableFuture.completedFuture("hello world");ExecutorService executor = Executors.newSingleThreadExecutor();CompletableFuture future = CompletableFuture        //第二个异步任务        .supplyAsync(() -> "hello siting", executor)        // (w, s) -> System.out.println(s) 是第三个任务        .thenCombineAsync(first, (s, w) -> {            System.out.println(s);            return "OK";        }, executor);System.out.println(future.join());executor.shutdown();--------输出结果--------hello sitingOK

4 、线程并行执行,谁先执行完则谁触发下一任务(二者选其最快)

上一个任务或者other任务完成, 运行action,不依赖前一任务的结果,无返回值

public CompletableFuture runAfterEither(CompletionStage other, Runnable action)   public CompletableFuture runAfterEitherAsync(CompletionStage other, Runnable action)public CompletableFuture runAfterEitherAsync(CompletionStage other,  Runnable action, Executor executor)
  • 使用示例

//第一个异步任务,休眠1秒,保证最晚执行晚CompletableFuture first = CompletableFuture.supplyAsync(()->{    try{ Thread.sleep(1000); }catch (Exception e){}    System.out.println("hello world");    return "hello world";});ExecutorService executor = Executors.newSingleThreadExecutor();CompletableFuture future = CompletableFuture        //第二个异步任务        .supplyAsync(() ->{            System.out.println("hello siting");            return "hello siting";        } , executor)        //() ->  System.out.println("OK") 是第三个任务        .runAfterEitherAsync(first, () ->  System.out.println("OK") , executor);executor.shutdown();--------输出结果--------hello sitingOK

上一个任务或者other任务完成, 运行action,依赖最先完成任务的结果,无返回值

public CompletableFuture acceptEither(CompletionStage other,  Consumer action)public CompletableFuture acceptEitherAsync(CompletionStage other,  Consumer action, Executor executor)       public CompletableFuture acceptEitherAsync(CompletionStage other,  Consumer action, Executor executor)
  • 使用示例

//第一个异步任务,休眠1秒,保证最晚执行晚CompletableFuture first = CompletableFuture.supplyAsync(()->{    try{ Thread.sleep(1000);  }catch (Exception e){}    return "hello world";});ExecutorService executor = Executors.newSingleThreadExecutor();CompletableFuture future = CompletableFuture        //第二个异步任务        .supplyAsync(() -> "hello siting", executor)        // data ->  System.out.println(data) 是第三个任务        .acceptEitherAsync(first, data ->  System.out.println(data) , executor);executor.shutdown();--------输出结果--------hello siting

上一个任务或者other任务完成, 运行fn,依赖最先完成任务的结果,有返回值

public  CompletableFuture applyToEither(CompletionStage other,  Function fn) public  CompletableFuture applyToEitherAsync(CompletionStage other,  Function fn)         public  CompletableFuture applyToEitherAsync(CompletionStage other,  Function fn, Executor executor)
  • 使用示例

//第一个异步任务,休眠1秒,保证最晚执行晚CompletableFuture first = CompletableFuture.supplyAsync(()->{    try{ Thread.sleep(1000);  }catch (Exception e){}    return "hello world";});ExecutorService executor = Executors.newSingleThreadExecutor();CompletableFuture future = CompletableFuture        //第二个异步任务        .supplyAsync(() -> "hello siting", executor)        // data ->  System.out.println(data) 是第三个任务        .applyToEitherAsync(first, data ->  {            System.out.println(data);            return "OK";        } , executor);System.out.println(future);executor.shutdown();--------输出结果--------hello sitingOK

5 、处理任务结果或者异常

exceptionally-处理异常

public CompletableFuture exceptionally(Function fn)
  • 如果之前的处理环节有异常问题,则会触发exceptionally的调用相当于 try...catch

  • 使用示例

CompletableFuture first = CompletableFuture        .supplyAsync(() -> {            if (true) {                throw new RuntimeException("main error!");            }            return "hello world";        })        .thenApply(data -> 1)        .exceptionally(e -> {            e.printStackTrace(); // 异常捕捉处理,前面两个处理环节的日常都能捕获            return 0;        });

handle-任务完成或者异常时运行fn,返回值为fn的返回

  • 相比exceptionally而言,即可处理上一环节的异常也可以处理其正常返回值

public  CompletableFuture handle(BiFunction fn) public  CompletableFuture handleAsync(BiFunction fn) public  CompletableFuture handleAsync(BiFunction fn,   Executor executor)
  • 使用示例

CompletableFuture first = CompletableFuture        .supplyAsync(() -> {            if (true) { throw new RuntimeException("main error!"); }            return "hello world";        })        .thenApply(data -> 1)        .handleAsync((data,e) -> {            e.printStackTrace(); // 异常捕捉处理            return data;        });System.out.println(first.join());--------输出结果--------java.util.concurrent.CompletionException: java.lang.RuntimeException: main error! ... 5 morenull

whenComplete-任务完成或者异常时运行action,有返回值

  • whenComplete与handle的区别在于,它不参与返回结果的处理,把它当成监听器即可

  • 即使异常被处理,在CompletableFuture外层,异常也会再次复现

  • 使用whenCompleteAsync时,返回结果则需要考虑多线程操作问题,毕竟会出现两个线程同时操作一个结果

public CompletableFuture whenComplete(BiConsumer action) public CompletableFuture whenCompleteAsync(BiConsumer action) public CompletableFuture whenCompleteAsync(BiConsumer action,  Executor executor)
  • 使用示例

CompletableFuture first = CompletableFuture        .supplyAsync(() -> {            if (true) {  throw new RuntimeException("main error!"); }            return "hello world";        })        .thenApply(data -> new AtomicBoolean(false))        .whenCompleteAsync((data,e) -> {            //异常捕捉处理, 但是异常还是会在外层复现            System.out.println(e.getMessage());        });first.join();--------输出结果--------java.lang.RuntimeException: main error!Exception in thread "main" java.util.concurrent.CompletionException: java.lang.RuntimeException: main error! ... 5 more

6 、多个任务的简单组合

public static CompletableFuture allOf(CompletableFuture... cfs)public static CompletableFuture anyOf(CompletableFuture... cfs)

  • 使用示例

 CompletableFuture future = CompletableFuture        .allOf(CompletableFuture.completedFuture("A"),                CompletableFuture.completedFuture("B"));//全部任务都需要执行完future.join();CompletableFuture future2 = CompletableFuture        .anyOf(CompletableFuture.completedFuture("C"),                CompletableFuture.completedFuture("D"));//其中一个任务行完即可future2.join();

7、取消执行线程任务

// mayInterruptIfRunning 无影响;如果任务未完成,则返回异常public boolean cancel(boolean mayInterruptIfRunning) //任务是否取消public boolean isCancelled()
  • 使用示例

CompletableFuture future = CompletableFuture        .supplyAsync(() -> {            try { Thread.sleep(1000);  } catch (Exception e) { }            return "hello world";        })        .thenApply(data -> 1);System.out.println("任务取消前:" + future.isCancelled());// 如果任务未完成,则返回异常,需要对使用exceptionally,handle 对结果处理future.cancel(true);System.out.println("任务取消后:" + future.isCancelled());future = future.exceptionally(e -> {    e.printStackTrace();    return 0;});System.out.println(future.join());--------输出结果--------任务取消前:false任务取消后:truejava.util.concurrent.CancellationException at java.util.concurrent.CompletableFuture.cancel(CompletableFuture.java:2276) at Test.main(Test.java:25)0

8、任务的获取和完成与否判断

// 任务是否执行完成public boolean isDone()//阻塞等待 获取返回值public T join()// 阻塞等待 获取返回值,区别是get需要返回受检异常public T get()//等待阻塞一段时间,并获取返回值public T get(long timeout, TimeUnit unit)//未完成则返回指定valuepublic T getNow(T valueIfAbsent)//未完成,使用value作为任务执行的结果,任务结束。需要future.get获取public boolean complete(T value)//未完成,则是异常调用,返回异常结果,任务结束public boolean completeExceptionally(Throwable ex)//判断任务是否因发生异常结束的public boolean isCompletedExceptionally()//强制地将返回值设置为value,无论该之前任务是否完成;类似completepublic void obtrudeValue(T value)//强制地让异常抛出,异常返回,无论该之前任务是否完成;类似completeExceptionallypublic void obtrudeException(Throwable ex)
  • 使用示例

CompletableFuture future = CompletableFuture        .supplyAsync(() -> {            try { Thread.sleep(1000);  } catch (Exception e) { }            return "hello world";        })        .thenApply(data -> 1);System.out.println("任务完成前:" + future.isDone());future.complete(10);System.out.println("任务完成后:" + future.join());--------输出结果--------任务完成前:false任务完成后:10

到此,关于"如何使用Java异步编程"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

任务 结果 两个 示例 输出 线程 处理 运行 三个 常量 消费 阻塞 编程 学习 环节 问题 休眠 保证 方法 更多 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 法院网络安全宣传周活动总结 网络安全清除痕迹 sql数据库决定对值 计算机网络技术类就业方向 专业计算机软件开发设施 静安区互联网软件开发出厂价格 服务器建站详细教程 网络技术公司英文客服用到的 委托书模板软件开发 linux宝塔打不开数据库 安卓软件开发平台 C语言 网络技术研究.理论 高校有几个服务器机房 中安共生互联网科技财商 数据库2021河北专科招生计划 黔江网络安全委员会 查询所在服务器超时 生死狙击2为什么显示服务器响应 中宁县政务软件开发怎么样 网络安全主要负责人是什么 校园安网络安全 水利信息网络安全开展情况 重庆办公系统软件开发哪家专业 别忽视金融网络安全 地理信息平台服务器配置 河南计算机软件开发哪家好 怎样删除本地数据库文件 深圳华宇互联网科技贵阳分公司 网络安全手抄报黑白困难 电子文件管理软件开发
0