精华内容
下载资源
问答
  • java使用多线程查询大批量数据

    万次阅读 热门讨论 2019-12-11 18:18:22
    前言 在某些时候,一旦单表数据量过大,查询数据的时候就会变得...这个查询的过程,数据量一旦过大,单线程查询数据将会成为瓶颈,下面尝试使用多线程来尝试查询一张数据量较大的表 由于代码逻辑不是很难,直接上...

    前言

    在某些时候,一旦单表数据量过大,查询数据的时候就会变得异常卡顿,虽然在大多数情况下并不需要查询所有的数据,而是通过分页或缓存的形式去减少或者避免这个问题,但是仍然存在需要这样的场景,比如需要导出一大批数据到excel中,导出数据之前,首先得把数据查询出来吧?这个查询的过程,数据量一旦过大,单线程查询数据将会成为瓶颈,下面尝试使用多线程来尝试查询一张数据量较大的表

    由于代码逻辑不是很难,直接上代码,关键的地方会有代码注释和说明,总体实现思路:

    • 查询表的数据总量
    • 线程切分,根据本机CPU的核数配置合适数量的线程处理数,根据数据总量为不同的线程分配不同的查询数据量分段,即不同的线程查询不同分段的数据
    • 将各个查询数据的线程提交至线程池,这里使用的线程是带有返回结果的异步线程

    1、测试控制器

    	@GetMapping("/getSysLogMulti")
        @ApiOperation(value = "多线程获取日志数据", notes = "多线程获取日志数据", produces = "application/json")
        public List getSysLogMulti() {
            return operLogService.getSysLogMulti();
        }
    

    2、业务实现类

       @Autowired
        private MultiThreadQueryUtil multiThr
    展开全文
  • java多线程实现大批量数据切分成指定份数的数据,然后多线程处理入库或者导出,线程的个数和每份数据的数量都可以控制
  • java使用多线程及分页查询数据量很大的数据 import org.springframework.beans.factory.annotation.Autowired; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util...

    java使用多线程及分页查询数据量很大的数据

     

    
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    public class QueryTest {
        @Autowired
        Object myService;
    
        public List<Map<String, Object>> getMaxResult(String sex) throws Exception {
            long start = System.currentTimeMillis();
            List<Map<String, Object>> result = new ArrayList<>();//返回结果
            int count = 20000005;//mydao.getCount(); 通过count查到数据总量
            int num = 10000;//每次查询的条数
            //需要查询的次数
            int times = count / num;
            if (count != 0) {
                times = times + 1;
            }         //开始查询的行数
            int bindex = 0;
            List<Callable<List<Map<String, Object>>>> tasks = new ArrayList<Callable<List<Map<String, Object>>>>();
            //添加任务
            for (int i = 0; i < times; i++) {
                Callable<List<Map<String, Object>>> qfe = new ThredQuery(myService, sex, bindex, num);
                tasks.add(qfe);
                bindex = bindex + num;
            }
            //定义固定长度的线程池  防止线程过多
            ExecutorService execservice = Executors.newFixedThreadPool(15);
            List<Future<List<Map<String, Object>>>> futures = execservice.invokeAll(tasks);
            // 处理线程返回结果
            if (futures != null && futures.size() > 0) {
                for (Future<List<Map<String, Object>>> future : futures) {
                    result.addAll(future.get());
                }
            }
            execservice.shutdown();  // 关闭线程池
            long end = System.currentTimeMillis();
            System.out.println("用时" + (start - end));
            return result;
        }
    }
    

     

    
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.Callable;
    
    public class ThredQuery implements Callable<List<Map<String, Object>>> {
        private Object myService;//需要通过够早方法把对应的业务service传进来 实际用的时候把类型变为对应的类型
        private String sex;//查询条件 根据条件来定义该类的属性
        private int bindex;//分页index
        private int num;//数量
    
        // /**      * 重新构造方法      * @param myService      * @param sex      * @param bindex      * @param num      */
        public ThredQuery(Object myService, String sex, int bindex, int num) {
            this.myService = myService;
            this.sex = sex;
            this.bindex = bindex;
            this.num = num;
        }
    
        @Override
        public List<Map<String, Object>> call() throws Exception {
            //通过service查询得到对应结果
            List<Map<String, Object>> list = new ArrayList<>();
    //        myService.queryBySex(sex,bindex,num);
            return list;
        }
    }
    

     

    展开全文
  • 最近在做一个数据抽取工作,因为涉及一些表的数据修改,因此写了个小工具。 主要用到技术: Mybatis , java多线程
  • 通过多线程处理大批量耗时业务,并返回结果。当监测到线程池中存在空闲线程时则动态向线程池中添加新的任务,直到所有任务执行结束。Demo为自己写的测试使用,下载后可直接运行测试。
  • 大批量数据多线程处理 原因:最近写项目多时候遇到一个这样的问题,Excel批量导入表格,数据量较大,处理时间较长。然后小编想到了可以用多线程处理。 例: //导入失败集合 List<BatchPayDetail...

     原因:

    最近写项目多时候遇到一个这样的问题,Excel批量导入表格,数据量较大,处理时间较长。然后小编想到了可以用多线程处理。

    例:

                    //导入失败集合
                    List<BatchPayDetailExcelDto> batchPayDetailExcelVoFailList = new CopyOnWriteArrayList<>();
                    //导入成功集合
                    List<BatchPayDetailExcelDto> batchPayDetailExcelVoSuccessList = new CopyOnWriteArrayList<>();
                    int totalSize = batchPayDetailList.size();   //总数量
                    final int[] currentNum = {0};          //当前处理数量
    /******************************************多线程处理开始*****************************************/
                    // 一百条为基准为一个线程处理
                    List<List<BatchPayDetailExcelDto>> groupList = CommonUtils.partition(batchPayDetailList, 100);
                    CountDownLatch countDownLatch = new CountDownLatch(groupList.size());
                    ExecutorService executorService = Executors.newFixedThreadPool(groupList.size());
    
                    for (int i = 0; i < groupList.size(); i++) {
                        int finalI = i;
                        executorService.execute(() -> {
                            List<BatchPayDetailExcelDto> batchPayDetailGroup = groupList.get(finalI);
                            for (BatchPayDetailExcelDto batchPayDetailExcel : batchPayDetailGroup) {
                                currentNum[0]++;
    
                                //创建业务消息信息  -- 导入进度
                                JSONObject obj = new JSONObject();
                                obj.put("cmd", MyConstants.PREFIX_CMD_PAY);//业务类型
                                obj.put("msgId", merchantId);//消息id
                                obj.put("msgTxt", CommonUtils.proportionInt(currentNum[0], totalSize).replace("%", ""));//当前导入进度
    //                            //单个用户发送 (userId为用户id)
                                webSocket.sendOneMessage(sysUser.getId(), obj.toJSONString());
    
                                String name = batchPayDetailExcel.getName();
                                String idCard = batchPayDetailExcel.getIdCard();
                                double money = batchPayDetailExcel.getFee();
                                if (!ValidUtil.validName(name.trim())) {
                                    batchPayDetailExcel.setRemark("名字校验失败!");
                                    batchPayDetailExcelVoFailList.add(batchPayDetailExcel);
                                    continue;
                                }
                                if (!ValidUtil.validIdCardNo(idCard.trim())) {
                                    batchPayDetailExcel.setRemark("身份证号校验失败!");
                                    batchPayDetailExcelVoFailList.add(batchPayDetailExcel);
                                    continue;
                                }
                                if (!ValidUtil.isNumber(money + "")) {
                                    batchPayDetailExcel.setRemark("金额校验失败,仅支持精确到两位小数!");
                                    batchPayDetailExcelVoFailList.add(batchPayDetailExcel);
                                    continue;
                                }
                                if (money < 10) {
                                    batchPayDetailExcel.setRemark("单笔代发交易金额不能低于10元!");
                                    batchPayDetailExcelVoFailList.add(batchPayDetailExcel);
                                    continue;
                                }
                                batchPayDetailExcelVoSuccessList.add(batchPayDetailExcel);
                            }
                            countDownLatch.countDown();
                        });
                    }
                    countDownLatch.await();
                    executorService.shutdown();   //关闭线程池

    注意:集合线程同步使用CopyOnWriteArrayList

    工具类

     /**
         * 集合按长度分组
         *
         * @param list
         * @param size
         * @param <T>
         * @return
         */
        public static <T> List<List<T>> partition(final List<T> list, final int size) {
            if (list == null) {
                throw new IllegalArgumentException("List must not be null");
    
    
            }
            if (size <= 0) {
                throw new IllegalArgumentException("Size must be greater than 0");
            }
            List<List<T>> result = new ArrayList<>();
            Iterator<T> it = list.iterator();
            List<T> subList = null;
            while (it.hasNext()) {
                if (subList == null) {
                    subList = new ArrayList<>();
                }
                T t = it.next();
                subList.add(t);
                if (subList.size() == size) {
                    result.add(subList);
                    subList = null;
                }
            }
            //补充最后一页
            if (subList != null) {
                result.add(subList);
            }
            return result;
    
        }
    

     

    展开全文
  • 主要介绍了Java多线程批量数据导入的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,下面小编和大家来一起学习下吧
  • 自己写的可以多线程并发处理数据流小工具,在n核处理器下使用小于n的线程数处理文件流,速度提升多倍(忘了好像是接近n-1倍)
  • 然后网上都说各种加索引,加索引貌似是有查询条件时在某个字段加索引比较快一些,但是毕竟是人家的库不能瞎动,再者说了,数据量偏大一点的,条件加上也还有好多数据怎么办,我想到了多线程的方式,话不多说,开始弄...

    我看到有的数据库是一万条数据和八万条数据还有十几万条,几百万的数据,然后我就想拿这些数据测试一下,发现如果用java和数据库查询就连一万多条的数据查询出来就要10s左右,感觉太慢了。然后网上都说各种加索引,加索引貌似是有查询条件时在某个字段加索引比较快一些,但是毕竟是人家的库不能瞎动,再者说了,数据量偏大一点的,条件加上也还有好多数据怎么办,我想到了多线程的方式,话不多说,开始弄

    多线程有好几种方式,今天说的方式比较好,实现Callable<> 这种方式能返回查询的数据,加上Future异步获取方式,查询效率大大加快

    线程类:
     

    package com.ThreadPoolHadel;
     
    import com.sqlSource.SqlHadle;
     
    import java.util.List;
    import java.util.concurrent.Callable;
     
    /**
     * Created by df on 2018/9/20.
     */
    public class ThredQuery implements Callable<List> {
     
     
        SqlHadle sqlHadle=new SqlHadle();
     
        private String search;//查询条件 根据条件来定义该类的属性
     
        private int bindex;//当前页数
     
        private int num;//每页查询多少条
     
        private String table;//要查询的表名,也可以写死,也可以从前面传
     
        private List page;//每次分页查出来的数据
     
        public  ThredQuery(int bindex,int num,String table) {
            this.bindex=bindex;
            this.num=num;
            this.table=table;
            //分页查询数据库数据
            page=sqlHadle.queryTest11(bindex,num,table);
        }
     
        @Override
        public List call() throws Exception {
            //返回数据给Future
            return page;
        }
    }
    
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.Callable;
     
    public class ThredQuery  implements Callable<List<Map<String, Object>>> {
        private Object myService;//需要通过够早方法把对应的业务service传进来 实际用的时候把类型变为对应的类型
        private String sex;//查询条件 根据条件来定义该类的属性
     
        private int bindex;//分页index
        private int num;//数量
     
        /**
         * 重新构造方法
         * @param myService
         * @param sex
         * @param bindex
         * @param num
         */
        public ThredQuery(Object myService,String sex,int bindex,int num){
            this.myService=myService;
            this.sex=sex;
            this.bindex=bindex;
            this.num=num;
        }
     
        @Override
        public List<Map<String, Object>> call() throws Exception {
            //通过service查询得到对应结果
            List<Map<String, Object>>  list  =new ArrayList<>(); //myService.queryBySex(sex,bindex,num);
     
            return list;
        }
    }

    调用类:

    package com.service;
     
     
    import com.ThreadPoolHadel.ThredQuery;
    import com.sqlSource.SqlHadle;
    import org.springframework.stereotype.Service;
     
    import java.util.ArrayList;
     
    import java.util.List;
    import java.util.concurrent.*;
     
    /**
     * Created by df on 2018/9/20.
     */
     
    @Service
    public class TheardQueryService {
     
        SqlHadle sqlHadle=new SqlHadle();
     
        public List<List> getMaxResult(String table) throws InterruptedException, ExecutionException {
            long start = System.currentTimeMillis();//开始时间
            List<List> result = new ArrayList<>();//返回结果
            //查询数据库总数量
            int count = sqlHadle.count(table);
            int num = 8000;//一次查询多少条
            //需要查询的次数
            int times = count / num;
            if (count % num != 0) {
                times = times + 1;
            }
            //开始页数  连接的是orcle的数据库  封装的分页方式  我的是从1开始
            int bindex = 1;
            //Callable用于产生结果
            List<Callable<List>> tasks = new ArrayList<>();
            for (int i = 0; i < times; i++) {
                Callable<List> qfe = new ThredQuery(bindex, num, table);
                tasks.add(qfe);
                bindex += bindex;
            }
            //定义固定长度的线程池  防止线程过多
            ExecutorService executorService = Executors.newFixedThreadPool(15);
            //Future用于获取结果
            List<Future<List>> futures=executorService.invokeAll(tasks);
            //处理线程返回结果
            if(futures!=null&&futures.size()>0){
                for (Future<List> future:futures){
                 result.addAll(future.get());
                }
            }
     
            executorService.shutdown();//关闭线程池
            long end = System.currentTimeMillis();
            System.out.println("线程查询数据用时:"+(end-start)+"ms");
            return result;
        }
     
     
    }
    
    
    
    //第二种调用方法
    import org.springframework.beans.factory.annotation.Autowired;
     
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
     
    public class QueryTest {
        @Autowired
        Object myService;
     
        public  List<Map<String, Object>> getMaxResult(String sex) throws Exception{
            long start = System.currentTimeMillis();
            List<Map<String, Object>> result=new ArrayList<>();//返回结果
            
            int count = 20000005;//mydao.getCount(); 通过count查到数据总量
     
            int num = 10000;//每次查询的条数
            //需要查询的次数
            int times=count / num;
            if(count%num !=0) {
                times=times+1;
            }
            //开始查询的行数
            int bindex = 0;
     
            List<Callable<List<Map<String, Object>>>> tasks = new ArrayList<Callable<List<Map<String, Object>>>>();//添加任务
            for(int i = 0; i <times ; i++){
                Callable<List<Map<String, Object>>> qfe = new ThredQuery(myService,sex,bindex, num);
                tasks.add(qfe);
                bindex=bindex+num;
            }
            //定义固定长度的线程池  防止线程过多
            ExecutorService execservice = Executors.newFixedThreadPool(15);
     
            List<Future<List<Map<String, Object>>>> futures = execservice.invokeAll(tasks);
                // 处理线程返回结果
            if (futures != null && futures.size() > 0) {
                for(Future<List<Map<String, Object>>> future : futures) {
                    result.addAll(future.get());
                }
            }
            execservice.shutdown();  // 关闭线程池
     
            long end = System.currentTimeMillis();
            System.out.println("用时"+(start-end));
            
            return result;
        }
    }
    
    

    19600多条数据3秒内查询完,对于之前10m查询完毕,已经提高很多的效率了

    80000多条数据7m就完成了

    830305万的数据需要40m ,哈哈哈,也算差不多一百万的数据了,最主要的是没有卡死,好像不经过处理很容易卡死

     

    5184121万的数据报GC了,那就演示到这吧,五百万的数据实在不适合这样查

    最主要的是,你的数据量大的话要相应的更改调用方法里的 num,一次性多查点,效率会高很多
    --------------------- 
    作者:dfBeautifulLive 
    来源:CSDN 
    原文:https://blog.csdn.net/dfBeautifulLive/article/details/82788830 
    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • https://www.cnblogs.com/qixing/p/9451714.html
  • Java多线程大批量同步数据(分页)

    千次阅读 2019-09-27 11:33:52
    背景 最近遇到个功能,两个月有300w+的数据,之后还在累加,因一开始该数据就全部存储在mysql表,现需要展示在...一开始同步的时候,采用单线程,循环以分页的模式去同步这两张表数据,结果是…一晚上,只同步了30...
  • 场景:查询接口、包括多个独立的业务逻辑查询数据、最后数据统一组装 普通的写法: controller类的方法 service类的方法 controller执行结果: 下面使用多线程技术进行优化 controller类的方法不变 ...
  • 如果有10亿数据要处理,利用分页处理,用线程池处理,如果每个线程处理5000条,开50个线程也不够用啊。 如果无限制开线cpu肯定承受不住,对于这种要怎么处理?
  • 主要介绍了利用Java多线程技术导入数据到Elasticsearch的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 多线程处理大量数据 java

    千次阅读 2020-09-27 17:12:11
    例如:获取大量数据并处理,生成execl文件导出 问题描述: 5W条数据处理后生成execl文件需要6个小时,效率慢 APP 中接收数据代码: @Override public void run() { bytes = mmInStream.read(buffer); mHandler....
  • 最近由于业务需要,数据量比较大,需要使用多线程来分批处理,提高处理效率和能力,于是就写了一个通用的多线程处理工具,只需要实现自己的业务逻辑就可以正常使用,现在记录一下 ResultBean类: 返回结果统一bean ...
  • 多线程实现大批量数据查询

    千次阅读 2019-01-25 14:32:17
    优化一个系统中的功能,需要通过判断进行次的查库,查库的性能是单表,条件有索引. public Map&lt;String, String&gt; getTopics(@RequestParam(“classroomIds”) List classroomIds) { Map&lt;String, ...
  • Java多线程处理大量数据

    万次阅读 2017-04-18 22:21:10
    并发环境是非常复杂的,什么情况都有可能发生,Java给我们提供了线程调度以及同步等机制来保证多线程环境下我们的代码依然可以正确执行,下面是多个线程处理大量数据的简单实现,入门级import java.util.ArrayList;...
  • JAVA-多线程模拟处理大量数据

    千次阅读 2018-11-26 16:45:26
    此处业务场景,可想象为,有大批量数据,需要添加到数据库   import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; ...
  • 主要为大家详细介绍了java导出大批量即百万以上数据的excel文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 最近有个业务需求要批量导出大量的数据,但数据库在面对过多数据查询时效率就会很慢,于是考虑使用多个线程来实现。 这里使用了Callable的方式创建多线程,好处是有返回值 package com.next.jiangzh.film.dao; ...
  • 现在有个需求是这样的:使用http调用第三方接口,获取数据后写入我们...但是现在接口请求会有大量的重复数据,导致数据库每天数据量,如果设置唯一约束,批量入库的时候数据库会发生死锁,有没有好的解决思路。</p>
  • 背景: 项目整合业务数据汇总录入数据库,数据规模为200~300w每月,按要求需要在月初导入上月全部数据。 要做到项目隔离。... 使用多线程执行批量入库操作(批量insert为300每次)。 使用countDownLa...
  • java多线程查询大量数据写入文件

    千次阅读 2017-04-28 15:14:21
    2.开启线程 public class TransmissionThread implements Runnable{ private final Logger logger = Logger.getLogger(TransmissionThread.class); private String name; Integer game_id; Integer draw_id; ...
  • java多线程处理数据

    2020-11-24 16:44:19
    在进行,处理大批量数据,程序执行缓慢,这时候就可以使用多线程, 同时对数据处理,此文章只作为借鉴,如有不足之处欢迎指出.废话不说,上代码↓ //构建线程池设置线程池的最大数量,线程池最大存活数量,线程池最大...
  • 多线程处理大量数据

    千次阅读 2020-04-15 18:12:34
    然后考虑用多线程处理。刚开始使用的是Executors.newFixedThreadPool(10)这种方式创建固定数量线程池;后面考虑到数据量大的时候,可能队列装不下,导致异常,然后换成了ExecutorService executorSer = new ...
  • 本人在实际中遇到过一个响应时间10s以上的接口,并且因为业务要求需要调用该接口很次(10000+),说白了就是单次的传参数获取一些数据,单个接口的数据量很小,但是对方没有提供批量数据获取的接口,木的办法。...
  • Java数据量多线程)分段分批处理

    万次阅读 热门讨论 2018-07-13 10:44:11
    package *.common.component...import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Execut...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,510
精华内容 5,004
关键字:

java使用多线程查询大批量数据

java 订阅