高效批量处理数据的 Java 方法
使用 Stream API 进行并行处理
Java 8 引入的 Stream API 支持并行流处理,可以充分利用多核 CPU 提升批量数据处理效率。通过 parallelStream() 方法将集合转换为并行流:
List<Data> dataList = getDataList();
dataList.parallelStream()
.filter(data -> data.isValid())
.map(data -> transform(data))
.forEach(result -> saveResult(result));
批处理与分批提交
对于数据库操作或网络请求,采用分批处理减少 I/O 开销。例如每 1000 条数据提交一次:
int batchSize = 1000;
List<Data> batch = new ArrayList<>(batchSize);
for (Data data : dataList) {
batch.add(data);
if (batch.size() >= batchSize) {
processBatch(batch);
batch.clear();
}
}
if (!batch.isEmpty()) {
processBatch(batch);
}
使用 Fork/Join 框架
对于计算密集型任务,Fork/Join 框架能自动拆分任务并行执行:
class DataProcessingTask extends RecursiveAction {
private final List<Data> dataList;
private final int start, end;
private static final int THRESHOLD = 1000;
protected void compute() {
if (end - start <= THRESHOLD) {
processSublist(dataList.subList(start, end));
} else {
int mid = (start + end) >>> 1;
invokeAll(
new DataProcessingTask(dataList, start, mid),
new DataProcessingTask(dataList, mid, end)
);
}
}
}
缓存优化
对频繁访问的数据使用缓存机制,如 Guava Cache 或 Caffeine:
LoadingCache<Key, Value> cache = Caffeine.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(key -> loadFromDatabase(key));
异步非阻塞处理
使用 CompletableFuture 实现异步流水线处理:
List<CompletableFuture<Result>> futures = dataList.stream()
.map(data -> CompletableFuture.supplyAsync(() -> process(data), executor))
.collect(Collectors.toList());
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream().map(CompletableFuture::join))
.thenAccept(results -> saveResults(results));
JVM 性能调优
针对大数据量处理调整 JVM 参数:
- 增加堆内存:
-Xms4g -Xmx4g - 使用 G1 垃圾回收器:
-XX:+UseG1GC - 设置年轻代大小:
-XX:NewRatio=2
数据库批量操作
使用 JDBC 批量更新提高数据库写入效率:
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement("INSERT INTO table VALUES (?,?)")) {
for (Data data : dataList) {
stmt.setObject(1, data.getValue1());
stmt.setObject(2, data.getValue2());
stmt.addBatch();
if (i % 1000 == 0) {
stmt.executeBatch();
}
}
stmt.executeBatch();
}
内存映射文件处理
对于超大文件处理,使用 java.nio 的内存映射技术:
try (RandomAccessFile file = new RandomAccessFile("large.dat", "r");
FileChannel channel = file.getChannel()) {
MappedByteBuffer buffer = channel.map(
FileChannel.MapMode.READ_ONLY, 0, channel.size());
while (buffer.hasRemaining()) {
process(buffer.getInt());
}
}

被折叠的 条评论
为什么被折叠?



