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(); }
相关推荐
异常君几秒前
高并发数据写入场景下 MySQL 的性能瓶颈与替代方案
java·mysql·性能优化
烙印6014 分钟前
MyBatis原理剖析(二)
java·数据库·mybatis
你是狒狒吗7 分钟前
TM中,return new TransactionManagerImpl(raf, fc);为什么返回是new了一个新的实例
java·开发语言·数据库
勤奋的知更鸟18 分钟前
Java编程之组合模式
java·开发语言·设计模式·组合模式
千|寻18 分钟前
【画江湖】langchain4j - Java1.8下spring boot集成ollama调用本地大模型之问道系列(第一问)
java·spring boot·后端·langchain
爱编程的喵32 分钟前
深入理解JavaScript原型机制:从Java到JS的面向对象编程之路
java·前端·javascript
on the way 12343 分钟前
行为型设计模式之Mediator(中介者)
java·设计模式·中介者模式
保持学习ing1 小时前
Spring注解开发
java·深度学习·spring·框架
techzhi1 小时前
SeaweedFS S3 Spring Boot Starter
java·spring boot·后端
异常君1 小时前
Spring 中的 FactoryBean 与 BeanFactory:核心概念深度解析
java·spring·面试