当前位置: 首页 > news >正文

开发一个网站系统报价h5网站制作平台

开发一个网站系统报价,h5网站制作平台,哈尔滨网站建设学校,网站建设要咨询哪些第1章:引言 大家好,我是小黑,今天,小黑要和大家聊聊CompletableFuture,这个Java 8引入的强大工具。 在Java传统的Future模式里,咱们都知道,一旦开始了一个异步操作,就只能等它结束…

7T7AlJ.png

第1章:引言

大家好,我是小黑,今天,小黑要和大家聊聊CompletableFuture,这个Java 8引入的强大工具。

在Java传统的Future模式里,咱们都知道,一旦开始了一个异步操作,就只能等它结束,无法知道执行情况,也不能手动完成或者取消。而CompletableFuture呢,就像它的名字一样,是可以"完全控制"的Future。它提供了更多的控制,比如可以手动完成,可以处理异常,还可以把多个Future组合起来,进行更复杂的异步逻辑处理。

对于现代Java程序员来说,掌握CompletableFuture是必不可少的。无论是提高程序的响应性能,还是编写更加清晰、更具可读性的代码,它都能大显身手。

第2章:基本概念解读

那么,CompletableFuture到底是什么呢?简单来说,它是一种异步编程工具,可以帮助咱们在未来的某个时刻完成一个计算结果。与Future最大的不同是,它可以被显式地完成,意味着咱们可以在任何时候设置它的值。

让我们来看一个简单的例子。假设小黑要从网上查询某个产品的价格,这是一个耗时的操作,使用CompletableFuture,咱们就可以异步地完成这个任务:

import java.util.concurrent.CompletableFuture;public class CompletableFutureDemo {public static void main(String[] args) {// 创建一个CompletableFuture实例CompletableFuture<String> futurePrice = CompletableFuture.supplyAsync(() -> {// 模拟耗时操作,比如调用外部APIsimulateDelay();return "100元";});// 在这里,咱们可以做一些其他的事情,不必等待价格查询的结果doSomethingElse();// 当结果准备好后,获取它String price = futurePrice.join();System.out.println("价格是:" + price);}private static void simulateDelay() {try {Thread.sleep(1000); // 模拟1秒的延迟} catch (InterruptedException e) {Thread.currentThread().interrupt();}}private static void doSomethingElse() {// 做一些其他的事情System.out.println("小黑在做其他的事情...");}
}

在这个例子中,supplyAsync方法创建了一个异步操作,模拟了一个耗时的价格查询过程。在查询价格的同时,主线程可以继续执行其他任务,比如doSomethingElse方法里的内容。当价格查询完成后,可以使用join方法来获取结果。这样的处理方式,让整个程序的执行效率大大提升,而且代码也更简洁明了。

CompletableFuture的美在于,它提供了一种新的编程范式,让咱们能够以声明式的方式描述复杂的异步逻辑。从上面的例子可以看出,CompletableFuture不仅让代码更加简洁,还让逻辑更加清晰,易于理解和维护。

第3章:创建CompletableFuture

1. 使用supplyAsync

最常见的创建方式是使用CompletableFuture.supplyAsync()。这个方法需要一个Supplier函数接口,通常用于执行异步计算。来看看小黑怎么用:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {// 模拟耗时的计算simulateTask("数据加载中");return "结果";
});

这个例子中,simulateTask模拟了一个耗时操作,比如从数据库加载数据。使用supplyAsync,咱们就能在另一个线程中执行这个任务,而主线程可以继续做其他事情。

2. 使用runAsync

如果咱们不关心异步任务的结果,只想执行一个异步操作,那就可以用runAsync。它接受一个Runnable函数接口,不返回任何结果:

CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {simulateTask("正在执行一些处理");
});

在这个例子里,simulateTask只是执行了一些操作,比如记录日志或者发送通知,但不返回任何内容。

3. 手动完成

有时候,咱们可能需要手动完成一个Future。比如,基于某些条件判断,决定是否提前返回结果。这时候可以用complete方法:

CompletableFuture<String> manualFuture = new CompletableFuture<>();
// 在某些条件下手动完成Future
if (checkCondition()) {manualFuture.complete("手动结果");
}

如果checkCondition返回true,那么这个Future就会被立即完成,否则它将保持未完成状态。

4. 组合使用

CompletableFuture真正的魅力在于它的组合能力。假设小黑有两个独立的异步任务,咱们可以这样组合它们:

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {simulateTask("加载用户数据");return "用户小黑";
});CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {simulateTask("加载配置信息");return "配置信息";
});// 组合两个future,等待它们都完成
CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (user, config) -> {return "处理结果: " + user + "," + config;
});

在这个例子中,thenCombine用于组合future1future2的结果。只有当这两个Future都完成时,才会调用thenCombine里的函数。

第4章:异步操作和链式调用

异步操作的力量

异步操作是指在一个线程中启动一个任务,让它在另一个线程中运行,从而不阻塞当前线程的执行。这在处理耗时任务时特别有用。举个例子,假设咱们要查询数据库,然后处理查询结果。如果同步执行,整个程序都得等着数据库查询完成,这就浪费了宝贵的时间。但如果用CompletableFuture实现异步,就可以在查询数据库的同时做其他事情。

链式调用的魅力

链式调用则是指一系列操作依次执行,前一个操作的结果作为下一个操作的输入。CompletableFuture支持多种链式调用方法,比如thenApply, thenAcceptthenRun

  • thenApply用于处理和转换CompletableFuture的结果。
  • thenAccept用于消费CompletableFuture的结果,不返回新的CompletableFuture。
  • thenRun则不关心前一个任务的结果,只是在前一个任务执行完后,执行一些后续操作。

来看看小黑准备的例子:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {simulateTask("查询数据库");return "查询结果";
});future.thenApply(result -> {// 对结果进行处理return "处理后的结果:" + result;
}).thenAccept(processedResult -> {// 消费处理后的结果System.out.println("最终结果:" + processedResult);
}).thenRun(() -> {// 执行一些不需要前一个结果的操作System.out.println("所有操作完成");
});

在这个例子里,小黑用supplyAsync启动了一个异步任务来查询数据库。然后用thenApply处理查询结果,用thenAccept消费处理后的结果,最后用thenRun标记所有操作完成。

通过这种方式,咱们可以构建出复杂的异步逻辑,而代码却依然保持清晰和易于管理。这就是CompletableFuture的魅力所在。

第5章:异常处理

基本异常处理

在CompletableFuture的世界里,如果异步操作失败了,异常会被捕获并存储在Future对象中。咱们可以使用exceptionally方法来处理这些异常。这个方法会返回一个新的CompletableFuture,它会在原来的Future抛出异常时执行。

来看个例子:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {if (new Random().nextBoolean()) {throw new RuntimeException("出错啦!");}return "正常结果";
}).exceptionally(ex -> {return "错误的回退结果:" + ex.getMessage();
});future.thenAccept(System.out::println);

这里,小黑创建了一个可能会失败的异步操作。如果抛出异常,exceptionally方法就会被调用,返回一个包含错误信息的回退结果。

细粒度的异常处理

有时候,咱们可能需要更细粒度的控制,比如只处理特定类型的异常,或者在异常发生时还想继续其他操作。这时候,可以用handle方法。它可以同时处理正常的结果和异常情况。

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {if (new Random().nextBoolean()) {throw new RuntimeException("出错啦!");}return "正常结果";
}).handle((result, ex) -> {if (ex != null) {return "处理异常:" + ex.getMessage();}return "处理结果:" + result;
});future.thenAccept(System.out::println);

在这个例子中,无论异步操作是成功还是失败,handle方法都会被调用。如果有异常,它会处理异常;如果没有,就处理正常结果。

管道式异常处理

CompletableFuture还允许咱们创建一个异常处理的“管道”,这样就可以把多个异步操作链接起来,并在链的任意位置处理异常。

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {// 第一个异步操作return "第一步结果";
}).thenApply(result -> {// 第二个异步操作,可能会出错throw new RuntimeException("第二步出错啦!");
}).exceptionally(ex -> {// 处理异常return "在第二步捕获异常:" + ex.getMessage();
}).thenApply(result -> {// 第三个异步操作return "第三步使用结果:" + result;
});future.thenAccept(System.out::println);

在这个例子中,小黑创建了一个包含三个步骤的异步操作链。如果第二步出错,异常会被捕获并处理,然后处理结果被传递到第三步。

第6章:组合与依赖

组合多个Future

最常用的方法之一是thenCombine。这个方法允许你组合两个独立的CompletableFuture,并且当它们都完成时,可以对它们的结果进行一些操作。

来看个例子:

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {simulateTask("加载用户信息");return "用户小黑";
});CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {simulateTask("加载订单数据");return "订单123";
});CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (userInfo, orderInfo) -> {return "合并结果:" + userInfo + "," + orderInfo;
});combinedFuture.thenAccept(System.out::println);

在这个例子中,future1future2代表两个独立的异步操作。只有当两者都完成时,thenCombine里面的函数才会执行,并且合并它们的结果。

依赖关系的处理

如果你的一个异步操作依赖于另一个异步操作的结果,那么可以使用thenCompose方法。这个方法允许你在一个Future完成后,以其结果为基础启动另一个异步操作。

CompletableFuture<String> masterFuture = CompletableFuture.supplyAsync(() -> {simulateTask("获取主数据");return "主数据结果";
});CompletableFuture<String> dependentFuture = masterFuture.thenCompose(result -> {return CompletableFuture.supplyAsync(() -> {simulateTask("处理依赖于" + result + "的数据");return "处理后的数据";});
});dependentFuture.thenAccept(System.out::println);

这个例子中,dependentFuture的执行依赖于masterFuture的结果。

处理多个Future

有时候,咱们可能有多个异步操作,需要等所有操作都完成后再进行下一步。这时候,可以使用CompletableFuture.allOf

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {simulateTask("任务一");return "结果一";
});CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {simulateTask("任务二");return "结果二";
});CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2);allFutures.thenRun(() -> {System.out.println("所有任务完成");
});

allOf会等待所有提供的Futures完成,然后执行后续操作。

第7章:最佳实践

1. 明智地选择异步任务执行方式

CompletableFuture提供了多种执行异步任务的方法,比如runAsyncsupplyAsync。默认情况下,它们使用公共的ForkJoinPool,但在某些场景下,你可能想要使用自定义的线程池来更好地控制资源。

ExecutorService customExecutor = Executors.newFixedThreadPool(10);
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {return "使用自定义线程池";
}, customExecutor);

这样做可以让你更好地管理线程资源,尤其是在处理大量异步任务时。

2. 谨慎处理阻塞操作

如果你的CompletableFuture链中包含阻塞调用,如数据库操作或文件I/O,最好是将这些操作放在独立的线程池中,避免阻塞ForkJoinPool中的线程。

ExecutorService dbExecutor = Executors.newCachedThreadPool();
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {// 这里是阻塞的数据库操作simulateTask("数据库操作");
}, dbExecutor);

这样可以防止长时间的阻塞操作占用过多的计算资源,影响整体性能。

3. 组合异步操作时的错误处理

当你组合多个CompletableFuture时,记得对每一个Future都进行错误处理。这样可以避免一个未捕获的异常破坏整个操作链。

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "任务1").exceptionally(ex -> "默认值1");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "任务2").exceptionally(ex -> "默认值2");CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (result1, result2) -> result1 + " 和 " + result2);

这样做确保了即使其中一个操作失败,整个链也可以继续执行。

4. 避免过多的链式调用

虽然链式调用是CompletableFuture的一个强大特性,但过度使用可能会导致代码难以理解和维护。建议把复杂的逻辑分解成多个方法或类。

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "原始数据").thenApply(this::step1).thenApply(this::step2).thenApply(this::step3);// 将每个步骤的逻辑封装在不同的方法中
private String step1(String data) {return "处理1:" + data;
}private String step2(String data) {return "处理2:" + data;
}private String step3(String data) {return "处理3:" + data;
}

第8章:总结

  1. 异步编程的强大工具:CompletableFuture为Java异步编程提供了强大的支持,让处理并发任务变得更简单、更灵活。

  2. 简化复杂逻辑:通过链式调用和组合多个异步任务,CompletableFuture能够帮助咱们以清晰的方式处理复杂的业务逻辑。

  3. 异常处理的优雅方式:CompletableFuture提供了一套完整的异常处理框架,让咱们能够更好地控制和管理异步代码中的错误情况。

http://www.hkea.cn/news/893759/

相关文章:

  • 网站优化的基本思想与原则百度号码
  • 沧州网站建设制作设计优化深圳seo优化推广
  • 建立一个网站需要什么技术网上培训机构
  • 网站设计与管理论文百度账号注册平台
  • 网站空间商推荐seo是什么职位缩写
  • 怎么建设boss网站文件外链
  • 百度推广网站建设费百度搜索引擎的网址是多少
  • php 手机网站 上传图片定制网站建设
  • 关于网站建设的问题百度关键词分析
  • 登录官方网站装修公司网络推广方案
  • 设计网站官网入口网站搜索优化方法
  • 网站优化qq群山东做网站
  • wordpress icomoon太原seo快速排名
  • 中华建设杂志网站记者数据指数
  • 网站开发测试情况南召seo快速排名价格
  • 上海仓储公司小红书seo优化
  • 南京建设公司网站网络营销整合推广
  • wordpress更改语言沈阳seo优化
  • wordpress免费网站世界大学排名
  • 做网站的属于什么专业?百度爱采购竞价推广
  • 网站建设一年多少恰东莞网站到首页排名
  • 新企业网站应该怎么做SEO优化广告联盟有哪些
  • 手机app开发网站建设软文推广文章案例
  • 网站自然排名百度经验官网登录
  • dz网站模板沧州网站优化公司
  • 桂林论坛天涯社区培训行业seo整站优化
  • 做伊瑞尔竞技场的网站搜索引擎简称seo
  • 46云虚拟主机股票发行ipo和seo是什么意思
  • 新泰做网站菏泽seo
  • 网站建设排名东莞seo收费