• 使用CyclicBarrier+线程池,按总页数分批次开多线程执行逻辑


      通过CyclicBarrier+线程池的方式,同步的方式分页分批次并发高效处理逻辑,将总页数分成多个批次并发执行每页逻辑,每个批次处理DO_MAX_SIZE个页,每个批次等待DO_MAX_SIZE个页数处理完成后才执行下一个批次,并等待所有批次执行完成才处理后续逻辑

      以下代码只需要在TODO处添加上自己的逻辑就可以达到处理效果

        /**
         * 线程池初始化,也可用其它初始化方式
         */
        private ExecutorService threadPool = new ThreadPoolExecutor(10, 50, 10L, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
    
        /**
         * 最大并发数量
         */
        final static int DO_MAX_SIZE = 8;
    
        /**
         * 线程批量并发执行数据,分页分线程处理,每页处理分配一个线程处理相关逻辑
         *  最大并发线程{@code DO_MAX_SIZE}
         * @param total 总条数
         * @author wl
         * @date 2019-08-20 18:21
         */
        private void executorMultiThreadPool (Long total) throws Exception {
            int startPage = 1, endPage = 0, pageSize = 200;
            // 按每页pageSize条算出总页数
            Long pageTotal = (total  +  pageSize  - 1) / pageSize;
            // 循环总页数然后按一组DO_MAX_SIZE个页来并发处理
            for (int i = 1; i <= pageTotal; i++) {
                endPage++;
                if (i % DO_MAX_SIZE != 0 && i != pageTotal) {
                    continue;
                }
                long timeStart = System.currentTimeMillis();
                int cbNum = endPage - startPage + 1;
                // 参数parties+1是因为给主线程添加了await,需要等待整个批次完成才执行后续逻辑;
                final CyclicBarrier cb = new CyclicBarrier(cbNum + 1);
                // 当前批次下需要处理的页数
                for (int page = startPage; page <= endPage; page++) {
                    final int pageNum = page;
                    threadPool.execute(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                // TODO: 处理当前页 pageNum 逻辑,此处可以查询pageNumb的数据,然后处理相关逻辑
                            } catch (Exception e) {
                                // TODO: 异常处理
                            } finally {
                                try {
                                    // 设置等待
                                    cb.await();
                                } catch (Exception e) {
                                    logger.info(">>>>>Finally处理异常", e);
                                }
                            }
                        }
                    });
                }
                // 等待全部处理
                try {
                    // 等待本批次全部处理完成
                    cb.await();
                } catch (Exception e) {
                    throw e;
                } finally {
                    logger.info(">>>>>线程池批次执行-批次完成用时[{}]", System.currentTimeMillis() - timeStart);
                }
                // 本批次处理完后,将结束页赋给开始
                startPage = endPage + 1;
            }
            logger.info(">>>>>线程池处理所有批次-执行完成");
        }
  • 相关阅读:
    安卓开发环境搭建
    css3实现漂亮的按钮链接
    mouseover与mouseenter的区别
    踩了一个在body上添加多个代理事件的坑
    javascript与生活:papago行车记录仪播放器golife无卫星图修复方法
    grunt入门之windows下搭建一个最基本的grunt项目
    一个简单的跨浏览器的弹出窗口的实现
    如何查询mysql中执行效率低的sql语句
    用PHP读写音频文件的信息(支持WMA和MP3)
    PHP功能类[获取客户端IP、页面跳转]
  • 原文地址:https://www.cnblogs.com/wanglu/p/11387044.html
Copyright © 2020-2023  润新知