创建线程池
@Configuration
public class TaskPoolConfig {
@Bean("taskExecutor")
public Executor taskExecutro(){
int i = Runtime.getRuntime().availableProcessors();
System.out.println("系统最大线程数 : "+i);
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(i);
taskExecutor.setMaxPoolSize(i);
taskExecutor.setQueueCapacity(99999);
taskExecutor.setKeepAliveSeconds(60);
taskExecutor.setThreadNamePrefix("taskExecutor--");
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
taskExecutor.setAwaitTerminationSeconds(60);
return taskExecutor;
}
}
多线程处理
思路
- 切分数据
- 计算出切分数量
- 创建CountDownLatch,个数为切分的数量
- 创建AtomicBoolean标记是否有异常,异常直接结束
- 多线程需要使用同一个数据库连接.设置为手动提交
- 子线程执行结束,判断标记是否true, true提交事务,false回滚
@Service
@RequiredArgsConstructor
public class UserService {
private final Executor taskExecutor;
private final UserMapper userMapper;
private final DataSource dataSource;
public User findById(Long id){
System.out.println("findById()...");
return userMapper.findById(id);
}
public void importExcel() throws SQLException, InterruptedException {
System.out.println("importExcel()...");
AtomicBoolean flag = new AtomicBoolean(true);
Connection connection = dataSource.getConnection();
List<User> list = new ArrayList<>();
IntStream.rangeClosed(1,12).forEach(i -> {
User user = User.builder()
.id(Long.parseLong(String.valueOf(i)))
.username("zlm" + i)
.email("zlm" + i + "@qq.com")
.password("zlm" + i)
.build();
list.add(user);
});
int sliceLength = 2;
int dataSize = list.size();
int splitSize =dataSize % sliceLength == 0 ? dataSize / sliceLength : dataSize / sliceLength + 1;
connection.setAutoCommit(false);
CountDownLatch cdl = new CountDownLatch(splitSize);
for (int i = 0; i < splitSize; i++) {
int index = i;
taskExecutor.execute(() -> {
if(index == splitSize - 1){
insertData(connection,flag,cdl, list.subList(splitSize * sliceLength , dataSize));
}else {
insertData(connection, flag, cdl, list.subList(index * sliceLength, (index + 1) * sliceLength));
}
});
}
cdl.await();
if(flag.get()){
connection.commit();
}else{
connection.rollback();
}
}
private void insertData(Connection connection,AtomicBoolean flag,CountDownLatch cdl, List<User> users) {
Random random = new Random();
long l = random.nextLong(100);
for (User user : users) {
if(flag.get()){
try {
Thread.sleep(1000);
PreparedStatement ps = connection.prepareStatement("insert into user(id,username,email,password) values(?,?,?,?)");
ps.setLong(1,user.getId());
ps.setString(2, user.getUsername());
ps.setString(3, user.getEmail());
ps.setString(4, user.getPassword());
ps.executeUpdate();
} catch (Exception e) {
flag.getAndSet(false);
}
}else{
break;
}
}
cdl.countDown();
}
}