Java CompletableFuture 详细使用教程与实践

news2024/10/7 10:23:43

一、Java CompletableFuture 详细使用教程

Java 8引入了一种强大的异步编程工具:CompletableFuture。它提供了一种处理异步计算的方式,使得你可以在计算完成时获取结果,或者将一个或多个 CompletableFuture 的结果组合在一起。本部分将详细解析 CompletableFuture 的各个方面,包括创建、组合、处理异常等,并通过示例来展示其使用方法。

1.1 创建 CompletableFuture

创建 CompletableFuture 的最简单方法是使用无参数构造函数:

CompletableFuture<Void> future = new CompletableFuture<>();

这将创建一个未完成的 CompletableFuture。你可以通过 complete 方法来完成它:

future.complete(null);

如果你想创建一个已经完成的 CompletableFuture,你可以使用 completedFuture 方法:

CompletableFuture<String> future = CompletableFuture.completedFuture("Hello, world!");

此外,你还可以使用 supplyAsync 方法来创建一个异步计算的 CompletableFuture

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    // 这里是一些长时间运行的计算
    return "Hello, world!";
});

1.2 处理 CompletableFuture 的结果

CompletableFuture 提供了一系列的方法来处理异步计算的结果。这些方法都返回一个新的 CompletableFuture,这样你可以将它们链接在一起形成一个处理管道。

例如,你可以使用 thenApply 方法来对结果进行转换:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")
        .thenApply(s -> s + ", world!");

你还可以使用 thenAccept 方法来消费结果:

CompletableFuture.supplyAsync(() -> "Hello")
        .thenAccept(s -> System.out.println(s + ", world!"));

如果你不关心结果,只想在计算完成后执行一些操作,你可以使用 thenRun 方法:

CompletableFuture.supplyAsync(() -> "Hello")
        .thenRun(() -> System.out.println("Computation finished."));

1.3 组合 CompletableFuture

CompletableFuture 提供了一系列的方法来组合多个异步计算。

例如,你可以使用 thenCompose 方法来将两个异步计算串联起来:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")
        .thenCompose(s -> CompletableFuture.supplyAsync(() -> s + ", world!"));

你还可以使用 thenCombine 方法来将两个异步计算并联起来:

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> ", world!");

CompletableFuture<String> future = future1.thenCombine(future2, String::concat);

如果你有多个 CompletableFuture,你可以使用 allOf 方法来等待它们全部完成:

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> ", world!");

CompletableFuture<Void> future = CompletableFuture.allOf(future1, future2);

1.4 处理 CompletableFuture 的异常

CompletableFuture 提供了两个方法来处理异常:exceptionally 和 handle

exceptionally 方法接受一个函数,这个函数将在计算抛出异常时被调用,它的返回值将作为新的结果:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    if (true) throw new RuntimeException("Exception!");
    return "Hello, world!";
}).exceptionally(ex -> "Sorry, we have an error!");

handle 方法和 exceptionally 类似,但是它可以处理正常的结果和异常:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    if (true) throw new RuntimeException("Exception!");
    return "Hello, world!";
}).handle((res, ex) -> {
    if (ex != null) {
        return "Sorry, we have an error!";
    } else {
        return res;
    }
});

以上就是 CompletableFuture 的主要用法。通过组合这些方法,你可以创建出复杂的异步处理管道,大大提高程序的性能和响应性。

二、使用 CompletableFuture 结合 MyBatis 和线程池批量插入数据

在处理大数据时,我们经常需要在数据库中插入大量的数据。如果我们使用传统的同步方法,可能会花费很长的时间。在这部分,我将展示如何使用 Java 的 CompletableFuture 进行异步处理,结合 MyBatis 和线程池来批量插入30万条数据,提高数据处理的效率。

2.1 创建线程池

首先,我们需要创建一个线程池,以便并发执行多个插入任务。我们可以使用 Java 的 Executors 类来创建线程池:

ExecutorService executor = Executors.newFixedThreadPool(10);

这将创建一个拥有10个线程的线程池。

2.2 创建数据

然后,我们需要创建要插入的数据。假设我们要插入一些用户数据,每个用户有一个名字和一个年龄:

class User {
    private String name;
    private int age;

    // getters and setters...
}

我们可以创建一个方法来生成用户数据:

List<User> generateUsers(int count) {
    List<User> users = new ArrayList<>();
    for (int i = 0; i < count; i++) {
        User user = new User();
        user.setName("User" + i);
        user.setAge(i % 100);
        users.add(user);
    }
    return users;
}

2.3 插入数据

接下来,我们需要创建一个方法来插入数据。我们将使用 MyBatis 的 SqlSession 来执行插入操作:

void insertUsers(SqlSession sqlSession, List<User> users) {
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    for (User user : users) {
        userMapper.insert(user);
    }
    sqlSession.commit();
}

注意,我们在插入所有用户后提交了事务。这是因为在大多数数据库中,事务提交是一个昂贵的操作,我们应该尽量减少事务提交的次数。

2.4 使用 CompletableFuture 插入数据

现在,我们可以使用 CompletableFuture 来并发插入数据。我们将数据分成多个批次,每个批次创建一个 CompletableFuture 来插入:

List<User> users = generateUsers(300000);
int batchSize = 1000;
List<CompletableFuture<Void>> futures = new ArrayList<>();

for (int i = 0; i < users.size(); i += batchSize) {
    List<User> batch = users.subList(i, Math.min(users.size(), i + batchSize));
    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            insertUsers(sqlSession, batch);
        }
    }, executor);
    futures.add(future);
}

CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

在上面的代码中,我们首先生成了300000个用户数据,然后将这些数据分成大小为1000的批次。对于每个批次,我们创建一个 CompletableFuture 来插入数据,然后将这个 CompletableFuture 添加到一个列表中。最后,我们使用 CompletableFuture.allOf 来等待所有的 CompletableFuture 完成。

2.5 关闭线程池

最后,我们需要关闭线程池。我们可以使用 ExecutorService.shutdown 方法来关闭线程池:

executor.shutdown();

这将等待所有已提交的任务完成,然后关闭线程池。

以上就是使用 CompletableFuture 结合 MyBatis 和线程池批量插入数据的方法。通过这种方式,我们可以大大提高插入数据的效率。希望这篇文章能帮助大家更好地理解和使用 CompletableFuture

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/949567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入了解Kubernetes(k8s):安装、使用和Java部署指南(持续更新中)

目录 Docker 和 k8s 简介1、kubernetes 组件及其联系1.1 Node1.2 Pod1.3 Service 2、安装docker3、单节点 kubernetes 和 KubeSphere 安装3.1 安装KubeKey3.2 安装 kubernetes 和 KubeSphere3.3 验证安装结果 4、集群版 kubernetes 和 KubeSphere 安装5、kubectl 常用命令6、资…

Node.js 是什么?Node.js 安装及配置环境 入门指南!

Node.js 是一个基于 Chrome V8 引擎的开源、跨平台的 JavaScript 运行时环境。它允许开发者使用 JavaScript 构建高性能、可扩展的网络应用程序&#xff0c;使 JavaScript 能够在服务器端运行&#xff0c;而不仅仅局限于浏览器端。Node.js 的包管理器 npm&#xff0c;是全球最大…

浅谈安防视频监控平台EasyCVR视频汇聚平台对于夏季可视化智能溺水安全告警平台的重要性

每年夏天都是溺水事故高发的时期&#xff0c;许多未成年人喜欢在有水源的地方嬉戏&#xff0c;这导致了悲剧的发生。常见的溺水事故发生地包括水库、水坑、池塘、河流、溪边和海边等场所。 为了加强溺水风险的提示和预警&#xff0c;完善各类安全防护设施&#xff0c;并及时发现…

直播程序源码OAuth协议:开放授权的重要性

什么是OAuth协议&#xff1f; OAuth协议又称为开放授权协议&#xff0c;是一种开放标准协议&#xff0c;OAuth协议被开发出来&#xff0c;主要用于授权用户去访问第三方的应用程序。在直播程序源码平台中&#xff0c;为了方便用户或是对接其他应用的功能&#xff0c;常常需要与…

【防火墙】防火墙双机热备

华为防火墙部署在网络出口位置时&#xff0c;如果发生故障会影响到整网业务&#xff0c;为提升网络的可靠性&#xff0c;需要部署两台华为防火墙并组成双机热备 一、双机热备概述 1、双机热备介绍 双机热备需要两台硬件和软件配置均相同的华为防火墙&#xff0c;两台华为防火墙…

【数据结构】| 并查集及其优化实现

目录 一. 并查集基本概念处理过程初始化合并查询小结 二. 求并优化2.1 按大小求并2.2 按秩(高度)求并2.3 路径压缩2.4 类的实现代码2.5 复杂度分析 三. 应用LeetCode 128: 最长连续数列LeetCode 547: 省份数量LeetCode 200: 岛屿数量 一. 并查集基本概念 以一个直观的问题来引入…

动态规划(Dynamic programming)讲解(线性 DP 篇)

文章目录 动态规划&#xff08;Dynamic Programing&#xff09;第一关&#xff1a;线性DP第一战&#xff1a; C F 191 A . D y n a s t y P u z z l e s \color{7F25DF}{CF191A.\space Dynasty\enspace Puzzles} CF191A. DynastyPuzzles题目描述难度&#xff1a; ☆☆☆ \color…

参与线上活动赢GLMR!在韩国和新加坡遇见Moonbeam

随着8月进入尾声&#xff0c;月圆人团圆的中秋节也已经近在眼前&#xff0c;凉爽的秋天将会为大地带来新的气象。而今年秋天对于区块链产业以及Moonbeam来说与以往不同&#xff0c;将是一个热闹且充满活动的季节。 9月初将会迎来韩国最大的区块链活动&#xff0c;韩国区块链周K…

M1 Pro 新芯片安装python2 方案汇总

前言&#xff1a;磨刀不误砍柴工&#xff0c;环境装好&#xff0c;才能打工。M1 Pro 新芯片安装python2 文章目录 方案一 docker 容器构造环境&#xff08;如果涉及本地两个仓库需要关联则不适用&#xff09;方案二 使用 pyenv &#x1f680; 作者简介&#xff1a;作为某云服务…

YAML详解及使用方法

YAML详解及使用方法 一、基本介绍二、数据类型2.1 纯量(scalars)/标量2.1.1 字符串2.1.2 保留换行(Newlines preserved)2.1.3 布尔值&#xff08;Boolean)2.1.4 整数&#xff08;Integer&#xff09;2.1.5 浮点数&#xff08;Floating Point&#xff09;2.1.6 空&#xff08;Nu…

WIN11右键菜单替换成WIN10右键菜单的办法

想必很多人已经都是使用上Win11的系统了。今天就来解决一个让人很无语的问题&#xff0c;就是这个win11的右键菜单。真的是太太太难用了。 能一步完成的操作&#xff0c;非要需要我多走一步。真的是麻了。 亲爱的Windows 11右键菜单&#xff0c;你的设计真是令人头疼。 那么我…

项目经理跨部门沟通的6个原则

大家好&#xff0c;我是老原。今天想和大家聊聊跨部门沟通。 你们在项目管理工作中&#xff0c;都是如何跨部门沟通&#xff0c;协调资源的&#xff1f; 项目经理80%的工作时间都是在沟通&#xff0c;一名优秀的项目经理&#xff0c;无疑是一个好的沟通者。 但不理解你的领导…

气象站的组成,有什么作用?

气象站的含义&#xff1a; 气象站是监测环境要素的仪器&#xff0c;比如&#xff1a;空气温度、空气湿度、风速、风向、大气压力、光照度等。气象站对环境要素的监测是通过不同传感器实现的&#xff0c;各个传感器既可以单独使用&#xff0c;也可以搭配使用&#xff0c;监测到…

董明珠怒斥员工「吃着碗里看着锅里」,如何看待?

导言&#xff1a; 最近&#xff0c;格力电器董事长董明珠因怒斥员工「吃着碗里看着锅里」的言论引起了广泛关注。这一事件激起了公众对职业素养和领导方式的讨论。本文将从职业素养的视角出发&#xff0c;探讨如何看待董明珠的怒斥员工事件。 领导者的压力与情绪管理 作为一位顶…

NCCoE发布“向后量子密码学迁移”项目进展情况说明书

近日&#xff0c;NIST下属的国家网络安全中心&#xff08;NCCoE&#xff09;发布了一份向后量子密码学迁移&#xff08;Migration to Post-Quantum Cryptography&#xff09;项目情况说明书。该文档简要概述了向后量子密码学迁移项目的背景、目标、挑战、好处和工作流程&#x…

2023年高教社杯 国赛数学建模思路 - 案例:最短时间生产计划安排

文章目录 0 赛题思路1 模型描述2 实例2.1 问题描述2.2 数学模型2.2.1 模型流程2.2.2 符号约定2.2.3 求解模型 2.3 相关代码2.4 模型求解结果 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 最短时…

使用Gitea自建仓库 并配置git上传

使用Gitea自建仓库 并配置git上传 使用 Docker 安装 | Gitea Documentation 1. 安装Docker 2. 使用Docker Compose快速安装 在安装目录下创建config 和 data两个文件夹 以下是我的配置&#xff0c;和官网提供的大差不差 version: "3"networks:gitea:external: …

c++入门——变量

专栏简介&#xff1a;为什么我要重新介绍c的相关知识&#xff0c;在此之前&#xff0c;我对于c的了解也仅仅是在表面。而在后来与c慢慢的接触中&#xff0c;c编程语言越来越让我觉得深奥&#xff0c;所以还是想要重新开创一个专栏来介绍c。对于c的介绍&#xff0c;本专栏会先介…

WebAssembly 在云原生中的实践指南

1 WebAssembly 介绍 WebAssembly&#xff08;Wasm&#xff09;是一种通用字节码技术&#xff0c;它可以将其他编程语言&#xff08;如 Go、Rust、C/C 等&#xff09;的程序代码编译为可在浏览器环境直接执行的字节码程序。 WebAssembly 的初衷之一是解决 JavaScript 的性能问…

1688API技术解析,实现按关键字搜索1688接口

要实现按关键字搜索1688商品&#xff0c;您可以使用1688提供的API来完成。下面是对1688 API的技术解析&#xff1a; 1. 注册成为1688开发者&#xff1a; 首先&#xff0c;您需要在1688开放平台上注册成为开发者&#xff0c;并创建一个应用以获取API访问权限。 2. 获取API访…