List数据分段以后再使用多线程执行

List数据分段以后再使用多线程执行,提高效率

大致业务场景,需要后台刷新产品详情缓存,for循环跑需要1个多小时才能执行完毕。
最后使用多线程处理,伪代码如下

//查询所有商品list ,商品较多几千只,不可能一下起几千线程处理。所以先将list分割
// PAGE_SIZE 可在配置中心设定,动态调整list分割数量
List<String> idList;
	int currentPage = 1;
		int pageSize = Integer.valueOf(PAGE_SIZE);
		int totalPage = idList.size() % pageSize>0?(idList.size() / pageSize)+1:idList.size() / pageSize;
		while (currentPage <= totalPage) {
			//把list分段
			List<String> currentList = pageBySubList(idList, currentPage, pageSize);
			//具体多线程处理逻辑
			executeRefreshDetail(currentList);
			currentPage += 1;
		}

 /**
	 * 这里是每一段list
	 * 然后使用多线程处理,利用CountDownLatch 机制,保证一批次全部处理完成后再进行下一段。防止过多任务,压垮下游服务
	 */
private void executeRefreshDetail(List<String> idList) {
		if (CollectionUtils.isEmpty(idList)) {
			return;
		}
		try {
			CountDownLatch countDownLatch = new CountDownLatch(idList.size());
			for (int i = 0; i < idList.size(); i++) {
				String id= idList.get(i);
				ThreadTaskPool.getThreadPool().execute(() -> {
					//这里拿到执行后返回的对象
					// 此前考虑使用Future,但get方法会阻塞线程,不能实现多线程调用
					BaseResult  baseResult = pofDetailsService.refreshDetailResult(id);
					log.info("{}执行结果{}", id, baseResult.getStatus());
					countDownLatch.countDown();
				});
			}
			countDownLatch.await(10, TimeUnit.MINUTES);
		} catch (Exception e) {
			log.error("任务执行失败,原因:{}", e);
		}
	}

/**
	 * 利用subList方法进行分页
	 * 
	 * @param list
	 *            分页数据
	 * @param pageSize
	 *            页面大小
	 * @param currentPage
	 *            当前页面
	 */
	protected static List<String> pageBySubList(List<String> list, int currentPage, int pageSize) {
		int totalcount = list.size();
		int pagecount = 0;
		List<String> subList;
		int m = totalcount % pageSize;
		if (m > 0) {
			pagecount = totalcount / pageSize + 1;
		} else {
			pagecount = totalcount / pageSize;
		}
		if (m == 0) {
			subList = list.subList((currentPage - 1) * pageSize, pageSize * (currentPage));
		} else {
			if (currentPage == pagecount) {
				subList = list.subList((currentPage - 1) * pageSize, totalcount);
			} else {
				subList = list.subList((currentPage - 1) * pageSize, pageSize * (currentPage));
			}
		}
		return subList;
	}

下图参考自:https://blog.csdn.net/u011726984/article/details/79320004
在这里插入图片描述
后续优化会尝试使用不同方式。但目前情况不需要获取结果归集。如有问题还请大家指出,谢谢。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,使用多线程的方式执行list集合数据,可以在Runnable对象中实现具体的任务逻辑,并通过线程池来管理多个线程执行。以下是一个示例代码: ```java import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; public class ThreadPoolExample { public static void main(String[] args) { // 创建一个包含5个线程线程池 ExecutorService executor = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); // 创建一个包含10个元素的List集合 List<Integer> list = new ArrayList<>(); for (int i = 1; i <= 10; i++) { list.add(i); } // 执行任务 for (Integer element : list) { executor.execute(new MyRunnable(element)); } // 关闭线程池 executor.shutdown(); } static class MyRunnable implements Runnable { private Integer element; public MyRunnable(Integer element) { this.element = element; } @Override public void run() { System.out.println("正在处理元素:" + element); } } } ``` 在这个示例中,我们定义了一个MyRunnable类,实现了Runnable接口,并在run()方法中实现了具体的任务逻辑。然后,我们使用for-each循环遍历List集合中的每个元素,并创建一个MyRunnable对象,并将其提交给线程池去执行。在MyRunnable的构造函数中,我们将List集合中的元素作为参数传入,并保存在成员变量中,在run()方法中使用。最后,我们关闭了线程池,等待所有任务都完成。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值