重新封装List的多种方法

本文探讨了在数据库分库分表后,如何优化大量数据的查询效率。通过对比不同编程方法,如线程执行、多线程、FutureTask及CompletableFuture,实测显示多线程与异步处理能显著提升查询速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我设计过数据库,也写过很多业务代码。我们设计数据库的时候,一般都是外键关联,每次需要外键涉及到的表的属性,都是直接关联查询或者用到的时候再去查询。原来没有分库分表,一个sql搞定。现在分库分表之后,发现每次都得二次查询。这样就需要针对查询出来的list再重新封装一次。

我们大家很熟悉的,都不用思考的就是这样写,至少我从来没测试过这样写的效率,

for(int i = 0;i<userInfoList.size;i++) { //for(UserInfo eachUserInfo:userInfoList)
    UserInfo eachUserInfo = userInfoList.get(i);
    UserInfoView userInfoView = new UserInfoView();
    userInfoView.setId(eachUserInfo.getId());
    userInfoView.setName(eachUserInfo.getName());
    userInfoView.setCarId(eachUserInfo.getCarId());
    userInfoView.setCarDesc(userInfoDao.queryCar(eachUserInfo.getCarId()));

    userInfoViewList.add(userInfoView);
});

今天看到一篇文章,让我大开眼界。于是测试了几种方法,发现效率真的很有差别。

先说一个线程执行到底,

  1. for(int i = 0;i<userInfoList.size;i++) {
  2. for(UserInfo eachUserInfo:userInfoList)
  3. userInfoList.foreach((eachUserInfo)->{}); //jdk1.8后引入
  4. userInfoList.stream().map(()->{}).collect(Collectors.toList());//jdk1.8后引入

我用600条数据做的测试,以上几种方式,都是需要3分钟左右。

然后改成多线程执行,

  • 用Executors框架
ExecutorService executorService = Executors.newCachedThreadPool();

Future<String> getJobDesc = executorService.submit(new Callable<String>() {
        @Override
        public String call() throws Exception {
            return userInfoDao.queryJob(userInfo.getJobId());
        }
    });
但是也用了3分钟左右
  • 用new Thread(),我是这么理解的,因为不能接受Callable类型的参数,所以借用了FutureTask
FutureTask<String> getJobDesc = new FutureTask<>(new Callable<String>() {
    @Override
    public String call() throws Exception {
        return userInfoDao.queryJob(userInfo.getJobId());
    }
});
new Thread(getJobDesc).start();
只用了1分钟。
  • 用CompletableFuture,
private Supplier<UserInfoDao> queryUtilsSupplier = UserInfoDao::new;
CompletableFuture<UserInfoDao> getJobDesc = CompletableFuture.supplyAsync(queryUtilsSupplier);
getJobDesc.thenAccept(new Consumer<UserInfoDao>() {
    @Override
    public void accept(UserInfoDao userInfoDao) {
        userInfoView.setJobDesc(userInfoDao.queryJob(userInfo.getJobId()));
    }
});
也用了1分钟左右。

请问我们是否有必要改成FutureTask或者CompletableFuture,还是得考虑一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值