多线程优化导入支持事务一

多线程优化导入支持事务一

    • 创建线程池
    • 多线程处理
        • 思路

创建线程池

@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;
    }
}

多线程处理

思路
  1. 切分数据
  2. 计算出切分数量
  3. 创建CountDownLatch,个数为切分的数量
  4. 创建AtomicBoolean标记是否有异常,异常直接结束
  5. 多线程需要使用同一个数据库连接.设置为手动提交
  6. 子线程执行结束,判断标记是否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();

//                    if(user.getId().equals(l)){
//                        int a = 1/0;
//                    }

                } catch (Exception e) {
                    flag.getAndSet(false);
                }
            }else{
                break;
            }
        }
        cdl.countDown();
    }
}

你可能感兴趣的:(java,java)