
业务背景:
有一批5~10W的Excel文件,使用Poi直接拿到了一个大的List集合,在进行业务遍历时,发现速度堪忧,5W数据大概要跑1个小时。决定使用多线程对其进行优化
第一步.声明一个线程池对象
此处直接定义一个线程池交由spring进行管理
- @EnableAsync @Component public class AsyncThreadPool {
- @Bean("ThreadPoolTaskExecutor")
- public ThreadPoolTaskExecutor initializeThreadPool() {
- ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor ();
- /**核心线程数:线程池创建时候初始化的线程数*/
- threadPool.setCorePoolSize(5);
- /**最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程*/
- threadPool.setMaxPoolSize(10);
- /**缓冲队列:用来缓冲执行任务的队列*/
- threadPool.setQueueCapacity(1000);
- /**允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁*/
- threadPool.setKeepAliveSeconds(30);
- /**缓冲队列满了之后的拒绝策略:由调用线程处理(一般是主线程)*/
- threadPool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
- /**初始化*/
- threadPool.initialize();
- return threadPool;
- }
- }
第二步,新建类,里面写具体业务逻辑代码,开启异步且指定线程池对象
- @Slf4j
- @Async("ThreadPoolTaskExecutor")
- @Component public class AsyncThreadUpdate {
- public Future 方法名(参数~可有可不有){
- 这里写具体业务逻辑
- return new AsyncResult(true);
- }
- }
第三步,在业务层分批处理数据并调用此异步方法
- List<Future<Boolean>> futures = new ArrayList<Future<Boolean>>(strList.size()/ThreadPool_NUM);
-
- List<String[]> sonList = strList.subList(i, i + toIndex);
- /**注入第二步的类,直接调用里面已经开启的异步方法*/
- Future<Boolean> future = asyncThreadUpdate.getThreadFuture(参数~可以不加); futures.add(future)
- for (Future<Boolean> future : futures) {
- /**调用get方法,等待所有异步线程执行完毕*/
- future.get();
- }
备注:
上面方法执行完毕后发现并不理想,是因为没有调用线程等待,即:等待所有的task任务结束后才继续往下执行