java 多线程分批检索数据并更新操作,如何提高效率?

配置: mac , 内存16G, 四核

环境:公司内网,本机连测试服务器。

数据量:23000000 表A

需求:简单点说就是表数据复制

把表A中的某个内容,复制到其他表中。

目前程序是启动 N 个线程,分批次并行执行, 每个线程执行 23000000 + 1 / N
总数量/线程数量= 每个线程要执行的数据量;

每个线程再分页操作,一次执行X次,X可配置。

目前个人理解:总数量 / N个线程 * X = 执行时间.

假设:线程数 N = 50 , 每次执行1000次.
比如:23000000 / 50 * 1000 = 总执行时间 。

那么在环境jvm配置 支持的前提下

应该是,线程数达到一个最大值,执行次数最优值。 达到最大效率。

可是现在是 相同执行次数下(比如,每次从数据库检索1000个数据,做逻辑判断),增加线程数量, 执行时间是原来的double。。

这是什么情况,谁能帮忙解释一下,针对这个问题。 该如何优化? 思路是否有问题。


我补充一下:

我做过这样的测试

1.单线程执行, 执行1次完整操作; 26ms

然后执行次数升到10,1000,5000. 分别是 会有相应时间上升。 大概1000次,会有600ms,5000次会在高点;

于是提升线程数量; 从单线程提升到10;20;50;执行时间就开始double了。。。。。。。。

每个进程执行 相对来说是相互独立的,执行相同的动作,就是执行的数据不同。

比如第一个线程执行0-1000个数据,第二个线程执行 1001- 2000的数据, 这样子。

IO密集型的任务不要贸然使用多线程,如果磁盘读写和网络成为瓶颈,多线程只会造成无谓的竞争条件和上下文切换。所以从单个线程开始,观察IO是否已经占满,没有才能逐步增加线程。

随着线程数的增加时间消耗增多是因为开的线程数太多了。由于你的机器是4核,所以在一般情况下物理上只能同时运行4个线程处理数据。开更多的线程会让内核更频繁切换线程,载入与保存上下文,这些都会消耗时间,降低了实际工作的效率。

要提高效率就应该取消多线程。多线程对服务器来说是个非常失败的设计。
几个核开几个进程,然后这几个进程的共享数据尽量少,这样才能快。

你的问题应该是出在数据库方面,你多线程同时操作数据库,读可能还好,但是你同时插入一个表就会涉及竞争,因为insert会加锁,建议你插入的那个表去掉所有的索引,主键也不要加,这样插入就不会加锁。
多线程的话建议你的线程数==你的核数,因为你的任务都是一样的IO等待,所以线程数太多没有好处,同时需要加大你的JVM内存。

发表评论

电子邮件地址不会被公开。 必填项已用*标注