多线程导出报表
场景描述
有一个企业级的报表系统,用户需要导出包含大量数据的报表,比如销售报表、财务报表等。这些报表可能涉及多个数据源(如数据库、文件等),并且数据量较大。如果使用单线程处理,可能会导致用户等待时间过长,甚至超时。因此,使用多线程可以显著提高报表导出的速度。
示例代码
假设报表需要从两个数据源(数据库和文件)获取数据,然后合并并导出为一个CSV文件。
1. 数据源接口
我们定义一个数据源接口,用于从不同来源获取数据。
java复制
public interface DataSource {
List<String> fetchData() throws Exception;
}
2. 数据源实现
定义两个数据源实现类,分别模拟从数据库和文件中获取数据。
java复制
public class DatabaseDataSource implements DataSource {
@Override
public List<String> fetchData() throws Exception {
System.out.println("Fetching data from Database...");
Thread.sleep(2000); // 模拟耗时操作
return Arrays.asList("Data1", "Data2", "Data3");
}
}
public class FileDataSource implements DataSource {
@Override
public List<String> fetchData() throws Exception {
System.out.println("Fetching data from File...");
Thread.sleep(1500); // 模拟耗时操作
return Arrays.asList("Data4", "Data5", "Data6");
}
}
3. 多线程任务
定义一个任务类,用于从数据源获取数据。
public class DataFetchTask implements Callable<List<String>> {
private DataSource dataSource;
public DataFetchTask(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public List<String> call() throws Exception {
return dataSource.fetchData();
}
}
4. 报表导出类
使用ExecutorService
来管理线程池,同时从多个数据源获取数据,并合并导出。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class ReportExporter {
public void exportReport() {
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(2);
// 创建任务
List<Future<List<String>>> futures = new ArrayList<>();
futures.add(executor.submit(new DataFetchTask(new DatabaseDataSource())));
futures.add(executor.submit(new DataFetchTask(new FileDataSource())));
// 等待所有任务完成
List<String> allData = new ArrayList<>();
for (Future<List<String>> future : futures) {
try {
allData.addAll(future.get()); // 获取任务结果
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
// 关闭线程池
executor.shutdown();
// 合并数据并导出
exportToCSV(allData);
}
private void exportToCSV(List<String> data) {
System.out.println("Exporting data to CSV...");
// 模拟导出到CSV文件
data.forEach(System.out::println);
}
public static void main(String[] args) {
ReportExporter exporter = new ReportExporter();
exporter.exportReport();
}
}