for(SysUser user : userList){
     user.setA(this.XXXService.getByIdAndCustomSelectSql(user.getId()));
     user.setB(this.XXXService.getByIdAndCustomSelectSql(user.getId()));
     user.setC(this.XXXService.getByIdAndCustomSelectSql(user.getId()));
     user.setD(this.XXXService.getByIdAndCustomSelectSql(user.getId()));
     user.setE(this.XXXService.getByIdAndCustomSelectSql(user.getId()));
}这种List遍历,每一次set都会查询一次数据库,上面一条执行完了才能执行下一条,用多线程优化这个过程,怎样可以让五条同步执行?

解决方案 »

  1.   

    这是个SQL 问题,并不需要多线程
      

  2.   

    fork/join就可以了
      

  3.   

    具体业务具体分析。
    比如你上面这个循环,是拿每个 userId 去查一次,这样查多次,为什么不先在Java层拿到所有IdList , 然后通过一个 SQL 去查询到结果集呢
      

  4.   

    一次查出abcde这5个值不是更好!?
      

  5.   

    考虑一下在数据库里写个函数,然后取出id集合,遍历id集合,调用函数
      

  6.   

    就MySQL而言,连接的建立是非常轻量的;相反,如果一次查询结果集过大,反而会影响性能。
      

  7.   

    用伪代码演示一下你目前的做法是:迭代id集合
    loop start
    --> 查询id对应的值(发送数据库请求,高I/O操作)
    --> 保存值的数据
    loop end显然,loop了多少次,你的高IO请求就做了多少次。
    可以优化的场景是降低发起高IO请求的次数,做批量处理id集合切分(50个id一个批次)
    loop start
    --> 查询50个id的值(发送数据库请求,高I/O操作)
    --> 保存50个值的数据
    loop end高IO的请求次数就降低为原有的1/50,实际上集合大小可控的话,完全可以不做循环一次查询出来。
      

  8.   

    自从JDK8开始,应该有听说过Lambda表达式吧,这里有个stream,Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。里面遍历会开启会自动多线程,可以看这篇文章http://www.nonelonely.com/article/1547605669187
      

  9.   

    我在review代码的时候遇到在循环中查数据库的就直接打回去。
    应该是先返回列表,客户端点击再返回详情。
      

  10.   

    害人的是你这种代码,可怕的是你的思想。发一个SQL到数据库查询,别想什么花花招数,把心思放在SQL和业务上。
      

  11.   

    你的问题不是怎么循环,而是考虑怎么优化你的sql
      

  12.   

    循环体内查db本就是很危险的,不建议再引入多线程,
    建议从自身业务需求入手,重新设计,无论是复杂的代码还是复杂的sql,都不是设计的捷径
      

  13.   

    通过 sql 把结果集查询出来,再赋值到对象中,需要用到多线程吗?for(SysUser user : userList){
         String yy = this.XXXService.getByIdAndCustomSelectSql(user.getId());
         user.setA(yy);
         user.setB(yy);
         user.setC(yy);
         user.setD(yy);
         user.setE(yy);
    }
      

  14.   

    ?一个user只需要更新一次,一批user其实也只需要更新一次