多线程并发处理批量业务数据<工具类>

一. 作用:提高业务代码编写效率,不用将精力浪费在如何将数据切断分配给工作线程。

二. 适用范围:使用多线程并发处理大批量任务数据时。

三. 注意:① 当线程中需要Bean对象时,可以使用ApplicationContext对象进行Bean对象的获取。

                 ② 具体线程并发数请根据实际Cpu内核数进行确认

                  ③ 基于spring提供的线程池,如果需要可以根据实际情况进行修改

上代码:

package com.example.demo;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;

/**
 * 提高开发效率,这里设置多线程处理策略
 */
public class SimpleThreadExecute<T> {

    /**
     * 待执行的数据集合
     */
    private ArrayList<T> list;

    /**
     * 执行任务的线程池
     */
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     * 当前任务最大并发线程数
     */
    private int loadThread;


    /**
     * 将数据集合交于指定线程处理
     */
    public SimpleThreadExecute(ArrayList<T> list, ThreadPoolTaskExecutor pool,int loadThread){
        this.list = list;
        this.loadThread = loadThread;
        this.threadPoolTaskExecutor = pool;
    }


    /**
     * 执行任务的方法
     */
    public void Execute(Class Thread){
        //程序计时
        long startTime = System.currentTimeMillis();

        //健壮性判断
        if (null!=list && list.size()>0 && null!=threadPoolTaskExecutor && loadThread>0){
            //计算每组数据量
            int load = list.size()/loadThread;
            System.out.println("数据量:"+list.size()+",每条线程执行的数量"+load);
            CountDownLatch countDownLatch = new CountDownLatch(loadThread);
            try{
                //数据分组,启动线程
                for (int i=0;i<loadThread;i++){
                    //最后一条线程处理所有任务
                    if (i==(loadThread-1)){
                        List<T> ts = list.subList(i * load, list.size());
                        threadPoolTaskExecutor.submit((Callable<? extends Object>) Thread.getConstructor(List.class,String.class,CountDownLatch.class).newInstance(ts,"线程"+i,countDownLatch));
                    }else {
                        List<T> ts = list.subList(i * load, i * load + load);
                        threadPoolTaskExecutor.submit((Callable<? extends Object>) Thread.getConstructor(List.class,String.class,CountDownLatch.class).newInstance(ts,"线程"+i,countDownLatch));
                    }
                }

                //等待所有线程执行完毕
                countDownLatch.await();
            }catch (Exception e){
                e.printStackTrace();
            }

            long endTime = System.currentTimeMillis();
            System.out.println("本次方法耗时:"+(endTime-startTime));
        }
    }

}

任务线程创建格式

这里需要注意任务线程的构造方法,参数的数量及顺序是与工具类中一致的

package com.example.Thread;

import com.example.Dto.Animal;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;

public class workThread implements Callable {

    /**
     * 需要处理的数据集合
     */
    private List<Animal> list;

    /**
     * 程序计数器
     */
    private CountDownLatch countDownLatch;

    /**
     * 线程名
     */
    private String threadName;

    public workThread (List<Animal> list, String threadName, CountDownLatch countDownLatch){
        this.list=list;
        this.threadName=threadName;
        this.countDownLatch=countDownLatch;
    }

    @Override
    public Object call() throws Exception {
        for (int i=0;i<list.size();i++){
            System.out.println(threadName+":"+list.get(i).getIndex());
        }
        countDownLatch.countDown();

        return null;
    }
}

如果希望在线程中使用Bean对象,那么可以基于ApplicationContext 的形式获取(例如数据查询写入以及关联其他业务代码等)

工具类初始化以及调用过程

SimpleThreadExecute<Animal> threadPoolTaskExecutor =
				new SimpleThreadExecute<>(animals, (ThreadPoolTaskExecutor) StringUtil.getBean("threadPoolTaskExecutor"), 8);
		threadPoolTaskExecutor.Execute(workThread.class);

获取Bean对象的工具类

package com.example.config;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class StringUtil implements ApplicationContextAware {

    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("加载上下文对象");
        context = applicationContext;
    }


    /**
     * 获取上下文对象
     * @return
     */
    public static ApplicationContext getApplicationContext(){
        return context;
    }


    public static Object getBean(String name){
        return getApplicationContext().getBean(name);
    }



    public static <T> T getBean(Class<T> requiredType) throws BeansException{
        return getApplicationContext().getBean(requiredType);
    }


}
 

如果各位大佬有修改意见,请留言支持一下哈,有帮助定期优化。感谢。


                
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值