批量VS多线程

本文讨论了在编程中遇到性能问题时如何利用批量处理和多线程来优化。批量处理通常能有效规避性能风险,特别是针对数据库操作和接口调用。当批量处理无法满足需求时,可以通过多线程进一步提升效率。文中展示了如何实现并行处理,并提供了相关代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在实际的编码过程中,总会遇到单一处理会有性能风险的问题,于是我们求助于批量或者多线程。

一、批量处理

        一般情况下批量处理就可以规避大部分性能风险的问题。将fetch(),改为batchFetch(),多数情况都比较简单,尤其是调用其他应用的接口时,将单一接口,换成批量接口即可;而最终主要是修改数据从数据库中的增删改查的方式。


二、多线程

        但是有时批量处理不能满足需求,比如需要调用外部的批量接口,但是外部接口不支持,或者可以添加批量接口,但是发现批量取数据库的效率仍然不满足性能需求,那么只能求助于多线程了,其中每个线程都是批量处理,这样更加提升了效率。


    /**
     * 并行处理控制参数
     */
    public class ParallelParameter {
        
        /**
         * 是否需要并行处理
         */
        private boolean isNeedParallel = false;
        
        /**
         * 单个线程是否需要批量处理
         */
        private boolean isNeedBatchProcessPerThread = false;
        
        /***
         * 单条线程处理的个数,默认为4
         */
        private int countPreThread = 4;
        
        public ParallelParameter() {}
        
        public ParallelParameter(boolean isNeedParallel, int countPreThread) {
            this.isNeedParallel = isNeedParallel;
            this.countPreThread = countPreThread;
        }
        
        public ParallelParameter(boolean isNeedParallel,boolean isNeedBatchProcessPerThread, int countPreThread) {
            this.isNeedParallel = isNeedParallel;
            this.countPreThread = countPreThread;
            this.isNeedBatchProcessPerThread = isNeedBatchProcessPerThread;
        }
    }

/**
* 串行
* @param userList
* @param dtoList
* @param code
* @param typeList
*/
private void serialBatch(List<User> userList, List<T> dtoList, String code, List<Type> typeList) {
List<T> dtoResult = processBatch(userList,code,typeList);
if(null != dtoResult) {
dtoList.addAll(dtoResult);
}
}

   /**
* 并行并且每个线程都是批量执行
* @param userList
* @param dtoList
* @param code
* @param typeList
*/
private void parallelBatch(final List<User> userList, final List<T> dtoList, final String code, final List<Type> typeList, final ParallelParameter parallelParameter) {
logger.info("Try to parallel process");
int size = userList.size();
if(0 == size) {
return;
}
int taskCount = (userList.size() + parallelParameter.countPreThread - 1) / parallelParameter.countPreThread;
logger.info(String.format("User count %d", size));
logger.info(String.format("Parallel process task count %d", taskCount));
// 这个等待所有的task完成一起返回
final CountDownLatch latch = new CountDownLatch(taskCount);
for(int i = 0; i < taskCount; i++) {
final int index = i;
threadpool.execute(new Runnable() {
@Override
public void run() {
try {
List<T> dtoResult = null;
int start = index * parallelParameter.countPreThread;
int end = start + parallelParameter.countPreThread;
if(end > userList.size()) {
end = userList.size();
}
List<User> newuserList = new ArrayList<User>();
for(; start < end; start++) {
newuserList.add(userList.get(start));
}
try {
dtoResult = processBatch(newuserList, code, typeList);
if(null != dtoResult) {
int i = 0;
for(int liststart = index * parallelParameter.countPreThread; liststart < end; liststart++){
dtoList.set(liststart, dtoResult.get(i));
i+=1;
}
}
} catch (Throwable t) {
logger.error("Process one User failed, skip", t);
}
} finally {
// 完成一个任务
latch.countDown();
}
}
});
}

// 等待所有的并行task完成
try {
latch.await();
} catch(InterruptedException e) {
logger.error("Wait parallel process failed, interrupted", e);
Thread.currentThread().interrupt();
}
}

/**
* 批量处理
* @param user
* @param code
* @param typeList
*/
protected List<T> processBatch(List<User> userList, String code, List<Type> typeList) {
List<T> dtoList = null;
if (null != code) {
List<User> newList = new ArrayList<User>();
for(User user : UserList){
if (code.equals(user.getMarker())) {
newList.add(user);
}
}
if(!newList.isEmpty()){
dtoList = this.getResouceList(newList, typeList);
}
} else {
dtoList = this.getResouceList(UserList, typeList);
}
return dtoList;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值