使用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(">>>>>线程池处理所有批次-执行完成"); }
如果你觉得不错,(点我)请我喝杯奶茶吧,O(∩_∩)O~
邮箱:wl131710@gmail.com、543253585@qq.com
★我的故乡江油市简介: 江油市是唐代大诗人李白的故乡,一座风景如画的历史文化名城,也是位于成都经济圈北端的一座正在崛起的新兴工业城市、旅游城市,素有“李白故里,九寨门户,蜀道咽喉,华夏诗城”之称。中国改革开放的总设计师邓小平为江油亲笔题写了“李白故里”四个苍劲有力的大字,近年来,又因著名武术大师海灯法师的影响而成为川北的武术之乡,可谓文武之光,交相辉映。此外,江油城郊的佛爷洞、金光洞均为川北名胜,作为古蜀道的重要通道,沿线古迹甚多。 李白纪念馆位于李白故里的昌明河畔,是一座具有唐代风格的古典园林建筑群,气韵飞动,豪放不羁,馆藏4000多件有关文物。