发布网友 发布时间:2022-05-01 09:28
共9个回答
懂视网 时间:2022-05-01 13:49
某需求需要处理千万级别的数据,按一定规则导出,生成txt或xml文件,单线程处理太慢,写了一个跑了看差不多要处理6~10个小时。想了想还是就用多线程来从数据库中limit不同的数据来进行处理,耗时控制在5分钟以内.相关逻辑为:
1 //……其他代码 2 int count = 10000000;//假设共1千万条数据需要读取 3 int per = 50000;//每次处理5万条 4 for (int i = 0 ; i < count/per ; i ++){ //创建1000/5=200个线程来处理数据 5 //使用线程池来处理多线程 6 ThreadPool.execute(new ProcessTask(i*per,per)); 7 }
8 //……其他代码 9 class ProcessTask implements Runnable{ 10 int beigin,num; 11 public ProcessTask(int begin,int num){ 12 this.begin = begin; 13 this.num = num; 14 } 15 @Overview 16 public void run (){ 17 //线程内容,读取数据 18 List<Data> userlist = XXXService.getDataByLimit(begin,num); 19 //……对读出来的数据进行处理 20 //……其他代码 21 } 22 }
可见,此处通过循环同时创建了200个线程,而这200个线程都需要读取数据库,测试环境下最大连接数设置的是20,此时数据库就容易报错,无法连接。
除了无法连接数据库以外,还可能会导致以下问题:
解决方案:
对读取数据库操作进行sleep
1 //……其他代码 2 int count = 10000000;//假设共1千万条数据需要读取 3 int per = 50000;//每次处理5万条 4 for (int i = 0 ; i < count/per ; i ++){ //创建1000/5=200个线程来处理数据 5 //使用线程池来处理多线程 6 ThreadPool.execute(new ProcessTask(i*per,per,i)); 7 } 8 //……其他代码 9 class ProcessTask implements Runnable{ 10 int beigin,num; 11 int i ; 12 public ProcessTask(int begin,int num,int i ){ 13 this.begin = begin; 14 this.num = num; 15 this.i = i ; 16 } 17 @Overview 18 public void run (){ 19 //线程内容,读取数据 20 Thread.sleep(i*500);//可以改成更大的值 21 List<Data> userlist = XXXService.getDataByLimit(begin,num); 22 //……对读出来的数据进行处理 23 //……其他代码 24 } 25 }
这样处理后就可以分时的读取数据库,减少服务器的负担,但是时间会变长(sleep操作),200*0.5=100s,不过也是在可以接受的范围内。
感觉好像也没多少技术含量……或者说把getDataByLimit方法设置成synchronizd就行了吧,如果是单独使用的情况下……
<--EOF-->
多线程读取数据库导致连接失败解决方案
标签:
热心网友 时间:2022-05-01 10:57
可以通过测试对错误原因进行排查,如果连接少量时不出问题,那就是连接量超出了某一数值出现异常,可以查看数据库的链接上限,如果是连接上限原因,可以尝试上调上限或者降低连接数量热心网友 时间:2022-05-01 12:15
1、数据库连接可以设置大一些,但是对性能会有影响热心网友 时间:2022-05-01 13:50
单机线程这么多没有实际意义吧,减少线程数,线程采用线程池热心网友 时间:2022-05-01 15:41
和线程池应该没关系,楼主这里应该是就是开启多个线程同时 长时间爬取,估计应该是有些线程存在并发问题,造成了线程死锁。可以用监控工具跟踪下。追问是java多线程的死锁还是数据库的,感觉两方面都有,有啥资料不追答JProfiler 跟踪看下吧
热心网友 时间:2022-05-01 17:49
用个connection pool嘛 dbcp热心网友 时间:2022-05-01 20:14
那就控制一个连接数热心网友 时间:2022-05-01 22:55
打酱油的,忽略!热心网友 时间:2022-05-02 01:53
使用线程池技术,不需要建立这么多数据库连接追问工程已经写到一定的地步了,我是想,从数据库方面考虑,怎么能处理下,改个参数之类的