java项目史上最简单的多线程使用方法(有demo)

提起多线程,开发的小伙伴都非常熟悉,今天我们来总结一下在企业中,我们是如何去使用线程和多线程去是我们的程序效率变快的!
介绍线程和多线程概念的文章有很多,今天我们举一个实际的案例来演示下!
案例:用户表中有10000条数据,假设我们需要一条一条的去更新用户的信息(一个接口全量更新用户的数据),然后再返回给客户端更新成功,那么怎么样可以提高我们的下效率呢?显然,如果用同步请求的方式,那实在是太慢了,客户估计还没等到程序跑完就已经开始跟你的产品经理投诉了!
我们有三种方案
1).使用mq消息进行业务解耦,将更新数据的操作交给mq消费者去做处理,接口直接返回给客户,告诉他处理成功!
2).后端接口写业务的时候直接开一个线程,让更新数据的操作在线程里面进行处理,然后返回处理成功给客户端!
3).后端接口开线程池,每个线程处理100个(或者更多的数据),然后做数据的聚合操作,全部处理完成以后再返回客户端数据处理成功!
方案1的代码就不写了,不是本文关心的主题。
方案2的代码如下:

/**
     * 使用单线程异步更新用户信息
     * @return
     * @throws InterruptedException
     */
    @RequestMapping(value = "/updateUserInfo", method = RequestMethod.GET)
    public String updateUserInfo() {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                //查询出用户表的前2000条数据,对这些数据做更新操作
                List<Users> users=usersService.getUsersByCount(2000);
                for (Users user:users){
                    String userName = user.getUserName().replace("帅哥","美女");
                    user.setUserName(userName);
                    usersService.updateById(user);
                }
            }
        });
        thread.start();
        return "completed";
    }

方案3的代码如下:

 /**
     * 批量更新用户信息
     * @return
     * @throws InterruptedException
     */
    @RequestMapping(value = "/updateBath", method = RequestMethod.GET)
    public String updateBath() {
        List<Future<Void>> futures = new ArrayList<>();
        //查询出用户表的前2000条数据,对这些数据做更新操作
        List<Users> users=usersService.getUsersByCount(2000);
        //将这20000条数据放到线程池里面做批量更新,将美女修改成帅哥
        int index = 0;
        List<Users> tempusers = new ArrayList<>();
        for(Users user:users){
            index++;
            tempusers.add(user);
            //每100条数据一组,放到线程池里面去做处理
            if (index % 100 == 0 || index == users.size()) {
                List<Users> tempusers2 = new ArrayList<>(Arrays.asList(new Users[tempusers.size()]));
                Collections.copy(tempusers2, tempusers);
                while (true) {
                    try{
                        Future<Void> futureRes = userHandler.updateBath(tempusers2);
                        futures.add(futureRes);
                        tempusers.clear();
                        break;
                    }catch(Exception e){
                        log.error("线程池已满,等待1秒");
                        try {
                            Thread.sleep(1000*5);
                        } catch (InterruptedException e1) {
                            log.error("InterruptedException!!!");
                        }
                    }
                }
            }
        }
        log.warn("updateBath 线程数:{}", futures.size());
        for (Future<Void> future : futures) {
            try {
                future.get();
            } catch (InterruptedException e) {
                log.error("updateBath 异步结果获取异常01!msg==>{}", ExceptionUtils.getStackTrace(e));
            } catch (ExecutionException e) {
                log.error("updateBath 异步结果获取异常02!msg==>{}", ExceptionUtils.getStackTrace(e));
            }
        }
        return "completed";
    }

其中userHandler.updateBath方法里面的代码如下:

@Async("testTaskExecutor")
    public Future<Void> updateBath(List<Users> users) {
        if (CollectionUtils.isEmpty(users)){
            return new AsyncResult<>(null);
        }
        for (Users user:users){
            String userName = user.getUserName().replace("美女","帅哥");
            user.setUserName(userName);
            usersService.updateById(user);
        }
        return new AsyncResult<>(null);
    }

当然可以使用Future的话,也可以使用它的子类CompletableFuture去写业务。这里就不做介绍了。
本文涉及demo可以在百度云盘中获取:
链接:https://pan.baidu.com/s/1JBhTG5rSPNhm6mI2scaaRg
提取码:73e9
欢迎大家留言讨论!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值