CompletableFuture+线程池使用案列

案例一

java 复制代码
@RestController
@RequestMapping("/export")
public class ExportController {

    private final ExecutorService executor = Executors.newFixedThreadPool(5);

    @GetMapping("/multiSheet")
    public void exportMultiSheet(HttpServletResponse response) throws Exception {
        // 构造5个CompletableFuture,每个处理自己的表和业务逻辑
        CompletableFuture<SheetData> future1 = CompletableFuture.supplyAsync(() -> handleUsers(), executor);
        CompletableFuture<SheetData> future2 = CompletableFuture.supplyAsync(() -> handleOrders(), executor);
        CompletableFuture<SheetData> future3 = CompletableFuture.supplyAsync(() -> handleProducts(), executor);
        CompletableFuture<SheetData> future4 = CompletableFuture.supplyAsync(() -> handleLogs(), executor);
        CompletableFuture<SheetData> future5 = CompletableFuture.supplyAsync(() -> handleCustomers(), executor);

        // 等待所有处理完成
        CompletableFuture<Void> allDone = CompletableFuture.allOf(future1, future2, future3, future4, future5);

        allDone.thenRun(() -> {
            try {
                response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                response.setCharacterEncoding("utf-8");
                String fileName = URLEncoder.encode("multi_sheet_export", "UTF-8");
                response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

                ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();

                // 依次写入每个Sheet(join获取数据)
                List<CompletableFuture<SheetData>> futures = Arrays.asList(future1, future2, future3, future4, future5);

                for (int i = 0; i < futures.size(); i++) {
                    SheetData data = futures.get(i).join();
                    WriteSheet sheet = EasyExcel.writerSheet(i, data.getSheetName())
                            .head(data.getHead())
                            .build();
                    excelWriter.write(data.getRows(), sheet);
                }

                excelWriter.finish();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                executor.shutdown(); // 一定要关闭线程池
            }
        }).join(); // 等待导出完成
    }

    // 示例方法,每个表处理逻辑不同
    private SheetData handleUsers() {
        // 查询 users 表,并处理逻辑(脱敏、计算、筛选等)
        return queryAndBuildSheet("users", "用户信息");
    }

    private SheetData handleOrders() {
        // 查询 orders 表,自定义业务逻辑处理
        return queryAndBuildSheet("orders", "订单信息");
    }

    private SheetData handleProducts() {
        return queryAndBuildSheet("products", "商品列表");
    }

    private SheetData handleLogs() {
        return queryAndBuildSheet("logs", "操作日志");
    }

    private SheetData handleCustomers() {
        return queryAndBuildSheet("customers", "客户信息");
    }

    // 通用方法:查询数据库并生成 SheetData
    private SheetData queryAndBuildSheet(String tableName, String sheetName) {
        List<List<String>> headers = new ArrayList<>();
        List<List<String>> rows = new ArrayList<>();

        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/your_db", "user", "password");
             PreparedStatement stmt = conn.prepareStatement("SELECT * FROM " + tableName);
             ResultSet rs = stmt.executeQuery()) {

            ResultSetMetaData meta = rs.getMetaData();
            int columnCount = meta.getColumnCount();

            List<String> headerRow = new ArrayList<>();
            for (int i = 1; i <= columnCount; i++) {
                headerRow.add(meta.getColumnLabel(i));
            }
            headers.add(headerRow);

            while (rs.next()) {
                List<String> row = new ArrayList<>();
                for (int i = 1; i <= columnCount; i++) {
                    Object val = rs.getObject(i);
                    // 可以在这里做字段处理,比如脱敏、格式转换等
                    row.add(val != null ? val.toString() : "");
                }
                rows.add(row);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return new SheetData(sheetName, headers, rows);
    }

    // SheetData结构,用于封装每个 Sheet 页的数据
    static class SheetData {
        private final String sheetName;
        private final List<List<String>> head;
        private final List<List<String>> rows;

        public SheetData(String sheetName, List<List<String>> head, List<List<String>> rows) {
            this.sheetName = sheetName;
            this.head = head;
            this.rows = rows;
        }

        public String getSheetName() { return sheetName; }

        public List<List<String>> getHead() { return head; }

        public List<List<String>> getRows() { return rows; }
    }
}

案例二

java 复制代码
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.net.URLEncoder;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

@RestController
public class ExportController {

    private final UserService userService;
    private final OrderService orderService;
    private final ProductService productService;
    private final CustomerService customerService;
    private final InvoiceService invoiceService;

    public ExportController(UserService userService,
                            OrderService orderService,
                            ProductService productService,
                            CustomerService customerService,
                            InvoiceService invoiceService) {
        this.userService = userService;
        this.orderService = orderService;
        this.productService = productService;
        this.customerService = customerService;
        this.invoiceService = invoiceService;
    }

    @GetMapping("/export")
    public void exportExcel(HttpServletResponse response) throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(5);

        try {
            CompletableFuture<List<User>> userFuture = CompletableFuture.supplyAsync(userService::list, executor);
            CompletableFuture<List<Order>> orderFuture = CompletableFuture.supplyAsync(orderService::list, executor);
            CompletableFuture<List<Product>> productFuture = CompletableFuture.supplyAsync(productService::list, executor);
            CompletableFuture<List<Customer>> customerFuture = CompletableFuture.supplyAsync(customerService::list, executor);
            CompletableFuture<List<Invoice>> invoiceFuture = CompletableFuture.supplyAsync(invoiceService::list, executor);

            CompletableFuture<Void> all = CompletableFuture.allOf(userFuture, orderFuture, productFuture, customerFuture, invoiceFuture);
            all.join(); // 等待全部完成

            List<User> users = userFuture.join();
            List<Order> orders = orderFuture.join();
            List<Product> products = productFuture.join();
            List<Customer> customers = customerFuture.join();
            List<Invoice> invoices = invoiceFuture.join();

            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("数据导出", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            // 写入多个 sheet
            ExcelWriter writer = EasyExcel.write(response.getOutputStream()).build();

            writer.write(users, EasyExcel.writerSheet(0, "用户").head(User.class).build());
            writer.write(orders, EasyExcel.writerSheet(1, "订单").head(Order.class).build());
            writer.write(products, EasyExcel.writerSheet(2, "产品").head(Product.class).build());
            writer.write(customers, EasyExcel.writerSheet(3, "客户").head(Customer.class).build());
            writer.write(invoices, EasyExcel.writerSheet(4, "发票").head(Invoice.class).build());

            writer.finish();
        } finally {
            executor.shutdown();
        }
    }
}

// 假设以下是实体类,省略 Getter/Setter
class User { private Long id; private String name; }
class Order { private Long id; private String number; }
class Product { private Long id; private String title; }
class Customer { private Long id; private String name; }
class Invoice { private Long id; private String invoiceNo; }

// 假设以下是 Service 接口
interface UserService { List<User> list(); }
interface OrderService { List<Order> list(); }
interface ProductService { List<Product> list(); }
interface CustomerService { List<Customer> list(); }
interface InvoiceService { List<Invoice> list(); }
相关推荐
麦兜*1 小时前
Spring Boot 整合量子密钥分发(QKD)实验方案
java·jvm·spring boot·后端·spring·spring cloud·maven
码破苍穹ovo2 小时前
堆----1.数组中的第K个最大元素
java·数据结构·算法·排序算法
2301_793086872 小时前
JVM 01 运行区域
java·开发语言
崎岖Qiu2 小时前
【JVM篇13】:兼顾吞吐量和低停顿的G1垃圾回收器
java·jvm·后端·面试
久念祈3 小时前
C++ - 仿 RabbitMQ 实现消息队列--服务端核心模块实现(五)
java·rabbitmq·java-rabbitmq
超级晒盐人6 小时前
用落霞归雁的思维框架推导少林寺用什么数据库?
java·python·系统架构·学习方法·教育电商
岁忧6 小时前
(LeetCode 面试经典 150 题) 138. 随机链表的复制 (哈希表)
java·c++·leetcode·链表·面试·go
鹦鹉0076 小时前
IO流中的字节流
java·开发语言·后端
你我约定有三6 小时前
分布式微服务--Nacos作为配置中心(二)
java·分布式·spring cloud·微服务·架构·wpf·负载均衡
qq_165706076 小时前
java实现运行SQL脚本完成数据迁移
java·sql