您的位置 首页 java

java使用线程池优化导入Excel功能

线程池优化导入Excel功能核心代码如下:

java使用线程池优化导入Excel功能

核心代码

 StopWatch stopWatch = new StopWatch("任务");
            stopWatch.start("处理数据");
            int totalSize = dataList.size();
            LOG.info("{},线程开始, 条数:{}", totalSize);
            List<Future> fuList = new ArrayList<>();
            /**
             * 设置线程池:
             *      线程池核心线程数
             *      线程池最大线程数
             *      空闲线程存活时间(过期回收)
             *      LinkedBlockingQueue: 阻塞队列
             *      拒绝处理策略:
             *          ThreadPoolExecutor.AbortPolicy():被拒绝后抛出RejectedExecutionException异常
             *          ThreadPoolExecutor.CallerRunsPolicy():被拒绝后给调用线程池的线程处理
             *          ThreadPoolExecutor.DiscardOldestPolicy():被拒绝后放弃队列中最旧的未处理的任务
             *          ThreadPoolExecutor.DiscardPolicy():被拒绝后放弃被拒绝的任务(当前新添加的任务)
             *
             */            ThreadPoolExecutor pool = new ThreadPoolExecutor(
                    8, 17, 60, TimeUnit.SECONDS,
                    new LinkedBlockingQueue<>(100), new ThreadPoolExecutor.DiscardOldestPolicy());
            int leftCount = totalSize % batchSize;
            int last = 0;
            for (int i = 0; i < totalSize / batchSize; i++) {
                int start = i * batchSize;
                last = start + batchSize;

                final List subList = dataList.subList(start, last);
                Future<?> f = pool.submit(new Runnable() {
                    @Override
                    public void run() {
                        doBusiness(subList,user, poetryTypeService, authorService, poetryService);
                    }
                });
                fuList.add(f);

            }

            final List leftList = dataList.subList(last, last + leftCount);

            if (leftList.size() > 0) {
                LOG.info("left data size:{}", leftList.size());
                Future<?> f = pool.submit(new Runnable() {
                    @Override
                    public void run() {
                  //你的业务逻辑
                        doBusiness(leftList,user, poetryTypeService, authorService, poetryService);
                    }
                });
                fuList.add(f);
            }

            for (Future fu : fuList) {
                fu.get();
            }
            pool.shutdown();
            stopWatch.stop();
            LOG.info("导入成功,总条数:{},{}", totalSize, stopWatch.prettyPrint());  

调用方式:

 ImportTask importTask = new ImportTaskMngImpl(list,  user,  poetryTypeService,  authorService,  poetryService);
                    importTask.exec();  

使用easypoi实现导入Excel功能:

 List<PoetryDTO> list =ExcelImportUtil.importExcel(file.getInputStream(),PoetryDTO.class, params);  

在使用线程池之前,需要先了解线程池!

创建线程池有俩种方式:通过Executors类提供的方法和通过ThreadPoolExecutor类自定义。

一、通过Executors类提供的方法

Executors类有四种线程池,分别是:

1.创建一个可缓存的线程池newCachedThreadPool

2. 创建一个固定大小的线程池newFixedThreadPool

3. 创建一个周期性的线程池 newScheduledThreadPool

4. 创建一个单线程的线程池 newSingleThreadExecutor

二、通过ThreadPoolExecutor类自定义

ThreadPoolExecutor类提供了4种构造方法,可根据需要来自定义一个线程池。

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        // 省略...
    }  

参数说明:

1. corePoolSize:核心线程数,线程池中始终存活的线程数。

2. maximumPoolSize: 最大线程数,线程池中允许的最大线程数。

3. keepAliveTime: 存活时间,线程没有任务执行时最多保持多久时间会终止。

4. unit: 单位,参数keepAliveTime的时间单位,7种可选。

参数

描述

TimeUnit.DAYS

TimeUnit.HOURS

小时

TimeUnit.MINUTES

TimeUnit.SECONDS

TimeUnit.MILLISECONDS

毫秒

TimeUnit.MICROSECONDS

微妙

TimeUnit.NANOSECONDS

纳秒

5. workQueue: 一个阻塞队列,用来存储等待执行的任务,均为线程安全,7种可选。

参数

描述

ArrayBlockingQueue

一个由数组结构组成的有界阻塞队列。

LinkedBlockingQueue

一个由链表结构组成的有界阻塞队列。

SynchronousQueue

一个不存储元素的阻塞队列,即直接提交给线程不保持它们。

PriorityBlockingQueue

一个支持优先级排序的无界阻塞队列。

DelayQueue

一个使用优先级队列实现的无界阻塞队列,只有在延迟期满时才能从中提取元素。

LinkedTransferQueue

一个由链表结构组成的无界阻塞队列。与SynchronousQueue类似,还含有非阻塞方法。

LinkedBlockingDeque

一个由链表结构组成的双向阻塞队列。

较常用的是LinkedBlockingQueue和Synchronous。线程池的排队策略与BlockingQueue有关。

6. threadFactory: 线程工厂,主要用来创建线程,默及正常优先级、非守护线程。

7. handler:拒绝策略,拒绝处理任务时的策略,4种可选,默认为AbortPolicy。

参数

描述

AbortPolicy

拒绝并抛出异常。

CallerRunsPolicy

重试提交当前的任务,即再次调用运行该任务的execute()方法。

DiscardOldestPolicy

抛弃队列头部(最旧)的一个任务,并执行当前任务。

DiscardPolicy

抛弃当前任务。

线程池的执行规则

当线程数小于核心线程数时,创建线程;

当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列;

当线程数大于等于核心线程数,且任务队列已满:若线程数小于最大线程数,创建线程,若线程数等于最大线程数,抛出异常,拒绝任务。

建议使用自定义类 ThreadPoolExecutor类来创建线程池!

文章来源:智云一二三科技

文章标题:java使用线程池优化导入Excel功能

文章地址:https://www.zhihuclub.com/174679.shtml

关于作者: 智云科技

热门文章

网站地图