专栏名称: Java基基
一个苦练基本功的 Java 公众号,所以取名 Java 基基
目录
相关文章推荐
HRTechChina  ·  【即将截止】2024-2025人力资源科技影 ... ·  昨天  
高绩效HR  ·  华为干部管理的四大工具.ppt ·  昨天  
薪人薪事企小薪  ·  劳动者在本单位连续工作满15年,且距法定退休 ... ·  2 天前  
中国企业家杂志  ·  王兴兴们的第一笔钱 ·  2 天前  
51好读  ›  专栏  ›  Java基基

老板:来,用Java实现一下这个报表功能,速度要快,要嘎嘎快!

Java基基  · 公众号  ·  · 2025-02-04 19:13

正文

👉 这是一个或许对你有用 的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入 芋道快速开发平台 知识星球。 下面是星球提供的部分资料:

👉 这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、 商城 、支付、工作流、大屏报表、微信公众号、 ERP CRM AI 大模型 等等功能:

  • Boot 多模块架构:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 微服务架构:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 17/21 + SpringBoot 3.3、JDK 8/11 + Spring Boot 2.7 双版本

来源:juejin.cn/post/
7350557995895701531


我们有一段业务,类似一个报表,就是获取用户的订单汇总,邮费汇总,各种手续费汇总,然后拿时间噶一卡,显示在页面。

但是呢,这几个业务没啥实际关系,数据也是分开的,一个一个获取会有点慢,我开始就是这样写的,老板嫌页面太慢,让我改,可是 页面反应慢,关我后端程序什么事 ,哥哥别打了,错了错了,我改,我改。那么最好的方案就是多线程分别获取然后汇总到一起返回。

在Java中获取异步线程的结果通常可以使用 Future Callable CompletableFuture FutureTask 等类来实现。这些类可以用来提交任务到线程池,并在任务完成后获取结果。这就是我们想要的结果,那么这里来深入研究分析一下这三个方案。

使用Future和Callable

package com.luke.designpatterns.demo;

import java.util.concurrent.*;

public class demo {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future future = executor.submit(new Callable() {
            public Integer call() throws Exception {
                // 获取各种汇总的代码,返回结果
                return 42;
            }
        });
        // 获取异步任务的结果
        Integer result = future.get();
        System.out.println("异步任务的结果是" + result);
        executor.shutdown();
    }
}

它们的原理是通过将任务提交到线程池执行,同时返回一个Future对象,该对象可以在未来的某个时刻获取任务的执行结果。

  • Callable 接口: Callable 是一个带泛型的接口,它允许你定义一个返回结果的任务,并且可以抛出异常。这个接口只有一个方法 call() ,在该方法中编写具体的任务逻辑。
  • Future 接口: Future 接口代表一个异步计算的结果。它提供了方法来检查计算是否完成、等待计算的完成以及检索计算的结果。Future 提供了一个 get() 方法,它会阻塞当前线程直到计算完成,并返回计算的结果。

Callable 接口本身并不直接启动线程,它只是定义了一个可以返回结果的任务。要启动一个 Callable 实例的任务,通常需要将其提交给 ExecutorService 线程池来执行。

ExecutorService 中,可以使用 submit(Callable task) 方法提交 Callable 任务。这个方法会返回一个 Future 对象,它可以用来获取任务的执行结果。

启动 Callable 任务的原理可以概括为以下几个步骤:

  • 创建 Callable 实例: 首先需要创建一个实现了 Callable 接口的类,并在 call() 方法中定义具体的任务逻辑,包括要执行的代码和返回的结果。
  • 创建 ExecutorService 线程池: 使用 Executors 类的工厂方法之一来创建一个 ExecutorService 线程池,例如 newFixedThreadPool(int nThreads) newCachedThreadPool() 等。
  • 提交任务: 将 Callable 实例通过 ExecutorService submit(Callable task) 方法提交到线程池中执行。线程池会为任务分配一个线程来执行。
  • 异步执行: ExecutorService 线程池会在后台异步执行任务,不会阻塞当前线程,使得主线程可以继续执行其他操作。
  • 获取结果: 通过 Future 对象的 get() 方法获取任务的执行结果。如果任务尚未完成, get() 方法会阻塞当前线程直到任务完成并返回结果。

总的来说,Callable 启动线程的原理是将任务提交给 ExecutorService 线程池,线程池会负责管理线程的执行,执行任务的过程是在独立的线程中进行的,从而实现了异步执行的效果。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

使用CompletableFuture

import java.util.concurrent.CompletableFuture;

public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        CompletableFuture future = CompletableFuture.supplyAsync(() -> {
            // 获取各种汇总的代码,返回结果
            return 43;
        });

        // 获取异步任务的结果
        Integer result = future.get();

        System.out.println("异步任务的结果:" + result);
    }
}

CompletableFuture 是 Java 8 引入的一个类,用于实现异步编程和异步任务的组合。它的原理是基于" Completable "(可以完成的)和" Future "(未来的结果)的概念,提供了一种方便的方式来处理异步任务的执行和结果处理。

CompletableFuture 的原理可以简单概括为以下几点:

  • 异步执行: CompletableFuture 允许你以异步的方式执行任务。你可以使用 supplyAsync() runAsync() 等方法提交一个任务给 CompletableFuture 执行,任务会在一个独立的线程中执行,不会阻塞当前线程。
  • 回调机制: CompletableFuture 提供了一系列的方法来注册回调函数,这些回调函数会在任务执行完成时被调用。例如, thenApply() , thenAccept() , thenRun() 等方法可以分别处理任务的结果、完成时的操作以及任务执行异常时的处理。
  • 组合多个任务: CompletableFuture 支持多个任务的组合,可以使用 thenCombine() thenCompose() thenAcceptBoth() 等方法来组合多个任务,实现任务之间的依赖关系。
  • 异常处理: CompletableFuture 允许你对任务执行过程中抛出的异常进行处理,可以使用 exceptionally() handle() 等方法来处理异常情况。
  • 等待任务完成: 与 Future 类似, CompletableFuture 也提供了 get() 方法来等待任务的完成并获取结果。但与传统的 Future 不同, CompletableFuture get() 方法不会阻塞当前线程,因为任务的执行是异步的。

总的来说, CompletableFuture 的原理是基于回调和异步执行的机制,提供了一种方便的方式来处理异步任务的执行和结果处理,同时支持任务的组合和异常处理。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

使用FutureTask

import java.util.concurrent.*;

public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        FutureTask futureTask = new FutureTask<>(() -> {
            // 获取各种汇总的代码,返回结果
            return 44;
        });

        Thread thread = new Thread(futureTask);
        thread.start();

        // 获取异步任务的结果
        Integer result = futureTask.get();
        System.out.println("异步任务的结果:" + result);
    }
}

FutureTask 是 Java 中实现 Future 接口的一个基本实现类,同时也实现了 Runnable 接口,因此可以被用作一个可运行的任务。 FutureTask 的原理是将一个可调用的任务( Callable Runnable )封装成一个异步的、可取消的任务,它提供了一个机制来获取任务的执行结果。







请到「今天看啥」查看全文