public Integer uploadUser1(List<UserVo> list, Integer uploadType) {
// 如果上传类型为全量替换,则先删除所有未删除的用户。
if (UserEnum.TOTAL_REPLACE.getValue().equals(uploadType)) {
userMapper.delete("deleted", String.valueOf(0));
}
// 使用AtomicInteger来线程安全地统计成功上传的用户数量。
// 使用AtomicInteger作为线程安全的计数器 这是一个线程安全的类,它的incrementAndGet方法保证了原子性,即使在多线程环境下也能正确地增加计数。
AtomicInteger successCounter = new AtomicInteger(0);
// 使用流式编程和CompletableFuture实现异步上传。
List<CompletableFuture<Void>> futures = list.stream()
// 统一设置用户密码。
// 由于peek操作不会改变流的元素顺序或产生新的集合,因此在此阶段不会引发并发问题。
.peek(userVo -> userVo.setPassword("123456"))
// 将用户信息转换为User对象,并异步插入数据库。
// CompletableFuture.runAsync: 这个方法用于异步执行给定的Runnable,每个CompletableFuture都是独立运行的,由executor管理调度。这意味着每个插入操作都在不同的线程中执行,相互之间不会直接冲突
.map(userVo -> CompletableFuture.runAsync(() -> {
User user = BeanUtils.toBean(userVo, User.class);
try {
userMapper.insert(user);
successCounter.incrementAndGet(); // 成功插入后计数器加1
} catch (Exception e) {
// 处理插入失败的情况
System.err.println("Failed to insert user: " + e.getMessage());
}
}, executor))
.collect(Collectors.toList());
// 等待所有异步任务完成。
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
// 返回成功上传的用户数量。
return successCounter.get(); // 返回成功插入的用户数量
}
坏处:频繁调用数据库